zoukankan      html  css  js  c++  java
  • 线性表->链式存储->线形链表(单链表)

    文字描述:

    为了表示前后两个数据元素的逻辑关系,对于每个数据元素,除了存储其本身的信息之外(数据域),还需存储一个指示其直接后继的信息(即直接后继的存储位置,指针域)。

    示意图:

    算法分析:

    在单链表中插入和删除元素时,主要是改变指针的值,其时间复杂度为1。而顺序存储的话,其时间复杂度为n。

    在单链表中求长度时不如顺序存储结构,其时间复杂度为n; 而顺序存储是1。故可以在链表头结点中设置一个长度值,在插入数据元素时加1,在删除数据元素时减1。

    在单链表中查找指定数据元素时,其时间复杂度和顺序存草时一样,乱序情况下为n。

    代码实现(动态单链表):

      1 //
      2 // Created by lady on 19-1-26.
      3 //
      4 
      5 #include <stdlib.h>
      6 #include <stdio.h>
      7 #include <string.h>
      8 
      9 //线性表的动态单链表存储结构
     10 typedef struct ElemType{
     11     char data[10];
     12 }ElemType;
     13 typedef struct LNode{
     14     ElemType e;
     15     struct LNode *next;
     16 }LNode, *LinkList;
     17 
     18 /*
     19  * 倒序法输入n个元素的值,建立带表头结点的单链表线性表L
     20  */
     21 static int CreateList_L(LinkList *L, int n, char name[])
     22 {
     23     printf("以倒插入法创建单链表存储结构的线性表%s:
    ", name);
     24     //先建立一个带头结点的单链表
     25     if((*L=(LinkList)malloc(sizeof(LNode))) == NULL){
     26         return -1;
     27     }
     28     (*L)->next = NULL;
     29     int i = 0;
     30     LinkList p = NULL;
     31     for(i=n; i>0; --i){
     32         //生成新的结点
     33         p = (LinkList)malloc(sizeof(LNode));
     34         //输入元素值
     35         printf("输入第%d个元素:", i);
     36         scanf("%s[^\n]", p->e.data);
     37         //插入到表头
     38         p->next = (*L)->next;
     39         (*L)->next = p;
     40     }
     41     return 0;
     42 }
     43 
     44 /*依次对L的每个数据元素调用函数fun。一旦fun失败,则操作失败*/
     45 static int ListTraverse_L(LinkList L, int (*fun)(ElemType,int), char info[])
     46 {
     47     printf("%s", info);
     48     //跳过头结点
     49     LNode *p = L->next;
     50     int i = 1;
     51     while(p){
     52         if(fun(p->e, i++)){
     53             printf("Err:when traverse(e,%d) wrong!
    ",i);
     54         }
     55         p = p->next;
     56     }
     57     printf("
    ");
     58 }
     59 
     60 /*
     61  * L为带头结点的单链表的头指针
     62  * 当第i个元素存在是,其值赋给e并返回0,否则返回-1
     63  */
     64 static int GetElem_L(LinkList L, int i, ElemType *e)
     65 {
     66     //初始化,p指向第一个结点
     67     LNode *p = L->next;
     68     //j为计数器
     69     int j = 1;
     70     while(p && j<i){
     71         //顺指针向后查找,知道p指向第i个元素或者p为空
     72         p = p->next;
     73         j+=1;
     74     }
     75     if(!p || j>i){
     76         //第i个元素不存在
     77         return -1;
     78     }
     79     //取第i个元素
     80     *e = p->e;
     81     return 0;
     82 }
     83 
     84 /*
     85  * 在带头结点的单链表线性表L中第i个位置之前插入元素e
     86  */
     87 static int ListInsert_L(LinkList *L, int i, ElemType e)
     88 {
     89     LNode *p = (LNode *)(*L);
     90     int j = 0;
     91     while(p && j<i-1){
     92         //寻找第i-1个结点
     93         p = p->next;
     94         ++j;
     95     }
     96     //i小于1或者大于表长+1
     97     if(!p || j>i)
     98         return -1;
     99     //生成新的结点
    100     LinkList s = (LinkList)malloc(sizeof(LNode));
    101     s->e = e;
    102     //将新结点插入到链表L中
    103     s->next = p->next;
    104     p->next = s;
    105     return 0;
    106 }
    107 
    108 /*
    109  * 在带头结点的单链线性表L中,删除第i个元素,并有e返回其值
    110  */
    111 static int ListDelete_L(LinkList *L, int i, ElemType *e)
    112 {
    113     LNode *p = (LNode *)(*L);
    114     LNode *q = NULL;
    115     int j = 0;
    116     while(p->next && (j<i-1)){
    117         //寻找第i个结点,并令p指向其前趋
    118         p = p->next;
    119         ++j;
    120     }
    121     if(!(p->next) || (j>i-1)){
    122         //删除位置不合理
    123         return -1;
    124     }
    125     //删除该结点
    126     q = p->next;
    127     p->next = q->next;
    128     *e = q->e;
    129     //释放该结点的占用空间
    130     free(q);
    131     return 0;
    132 }
    133 
    134 /*
    135  * 输入元素e的数据和位置
    136  */
    137 static int printE(ElemType e, int location)
    138 {
    139     printf("%3d=%-10s", location, e.data);
    140     return 0;
    141 }
    142 
    143 /*
    144  * 已知单链线性表La和Lb的元素按值非递减排列
    145  * 归并La和Lb得到新的单链线性表Lc,Lc的元素也按值非递减排列
    146  */
    147 static void MergeList_L(LinkList La, LinkList Lb, LinkList *Lc)
    148 {
    149     LNode *pa = La->next;
    150     LNode *pb = Lb->next;
    151     LNode *pc = NULL;
    152     LNode *p;
    153     //用La的头结点作为Lc的头结点
    154     pc = (LNode*)La;
    155     *Lc = La;
    156 
    157     while(pa && pb){
    158         if(atoi(pa->e.data) <= atoi(pb->e.data)){
    159             //需要将当前的pa结点插入到pc结点
    160             if(pc->next == pa){
    161                 //pc结点正好在pa链表
    162                 pc = pc->next;//移动pc结点到下一个结点
    163                 pa = pa->next;//移动pa结点到下一个结点
    164             }else{
    165                 //需要将pa结点插入到pc结点后,插入后pc、pa结点要后移动
    166                 p = pa;
    167                 pa = pa->next;
    168                 p->next = pc->next;
    169                 pc->next = p;
    170                 pc = pc->next;
    171             }
    172         }else{
    173             if(pc->next == pb){
    174                 pc = pc->next;
    175                 pb = pb->next;
    176             } else{
    177                 p = pb;
    178                 pb = pb->next;
    179                 p->next = pc->next;
    180                 pc->next = p;
    181                 pc = pc->next;
    182             }
    183         }
    184     }
    185     //插入剩余段
    186     pc->next = pa?pa:pb;
    187     //释放Lb的头结点
    188     free(Lb);
    189 }
    190 
    191 /*
    192  * 释放链表L
    193  */
    194 static int DestoryList_L(LinkList *L)
    195 {
    196     if(L == NULL){
    197         return -1;
    198     }
    199     if(*L == NULL){
    200         return -1;
    201     }
    202     LNode *p, *q;
    203     p = (LNode*)(*L);
    204     while(p){
    205         q = p;
    206         free(q);
    207         p = p->next;
    208     }
    209     *L = NULL;
    210     return 0;
    211 }
    212 
    213 int main(int argc, char *argv[])
    214 {
    215 
    216     ElemType e;
    217     int location = 0;
    218 
    219     LinkList L;
    220     CreateList_L(&L, 4, "L");
    221     ListTraverse_L(L, printE, "L:");
    222 
    223     printf("insert a data and print, please input (location, data):");
    224     scanf("%d,%s[^\n]", &location, e.data);
    225     ListInsert_L(&L, location, e);
    226     ListTraverse_L(L, printE, "L:");
    227     printf("
    ");
    228 
    229     printf("delete a data through location and print, please input (location):");
    230     scanf("%d[^\n]", &location);
    231     ListDelete_L(&L, location, &e);
    232     printf("location %d, data %s is deleted from List
    ", location, e.data);
    233     ListTraverse_L(L, printE, "init:");
    234     printf("
    ");
    235 
    236     printf("locate/find a data through location, please input (location):");
    237     scanf("%d[^\n]", &location);
    238     GetElem_L(L, location, &e);
    239     printf("the data of what location is %d, is %s
    ", location, e.data);
    240     printf("
    ");
    241 
    242     printf("Merge LA and LB to  LC!
    ");
    243     LinkList La, Lb, Lc;
    244     //create La
    245     CreateList_L(&La, 4, "La");
    246     ListTraverse_L(La, printE, "La:");
    247     //create Lb
    248     CreateList_L(&Lb, 7, "Lb");
    249     ListTraverse_L(Lb, printE, "Lb:");
    250     //merge La and Lb to Lc
    251     MergeList_L(La, Lb, &Lc);
    252     ListTraverse_L(Lc, printE, "Lc:");
    253 
    254     DestoryList_L(&L);
    255     DestoryList_L(&La);
    256     DestoryList_L(&Lb);
    257 }
    动态单链表

     代码运行(动态单链表):

    /home/lady/CLionProjects/untitled/cmake-build-debug/untitled
    以倒插入法创建单链表存储结构的线性表L:
    输入第4个元素:ZHAO
    输入第3个元素:QIAN
    输入第2个元素:SUN
    输入第1个元素:LI
    L:  1=LI          2=SUN         3=QIAN        4=ZHAO      
    insert a data and print, please input (location, data):2,ZHOU
    L:  1=LI          2=ZHOU        3=SUN         4=QIAN        5=ZHAO      
    
    delete a data through location and print, please input (location):3
    location 3, data SUN is deleted from List
    init:  1=LI          2=ZHOU        3=QIAN        4=ZHAO      
    
    locate/find a data through location, please input (location):3
    the data of what location is 3, is QIAN
    
    Merge LA and LB to  LC!
    以倒插入法创建单链表存储结构的线性表La:
    输入第4个元素:11
    输入第3个元素:8
    输入第2个元素:5
    输入第1个元素:3
    La:  1=3           2=5           3=8           4=11        
    以倒插入法创建单链表存储结构的线性表Lb:
    输入第7个元素:20
    输入第6个元素:15
    输入第5个元素:11
    输入第4个元素:9
    输入第3个元素:8
    输入第2个元素:6
    输入第1个元素:2
    Lb:  1=2           2=6           3=8           4=9           5=11          6=15          7=20        
    Lc:  1=2           2=3           3=5           4=6           5=8           6=8           7=9           8=11          9=11         10=15         11=20        
    
    Process finished with exit code 0

    代码实现(带头结点的单向动态链表)

      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <string.h>
      4 
      5 //带头结点的线性链表类型定义如下
      6 typedef struct ElemType{
      7     char data[10];
      8 }ElemType;
      9 typedef struct LNode{//结点类型
     10     ElemType e;
     11     struct LNode *next;
     12 }*Link, *Position;
     13 typedef struct {//链表类型
     14     Link head,tail;//分别指向线性链表中的头结点和最后一个结点
     15     int len;//指示线性链表中数据元素的个数
     16 }LinkList;
     17 
     18 /*
     19  *依次对L的每个元素调用visit函数,一旦失败,则操作失败
     20  */
     21 static int ListTraverse(LinkList L, int (*visit)(ElemType,int), const char note[])
     22 {
     23     printf("遍历线性表%s:", note);
     24     Link p = L.head->next;
     25     int i = 1;
     26     while(p){
     27         if(visit(p->e,i)<0){
     28             return -1;
     29         }
     30         if(p==L.tail)
     31             break;
     32         p = p->next;
     33     }
     34     printf("
    ");
     35     return 0;
     36 }
     37 
     38 static int print(ElemType e, int loc)
     39 {
     40     printf("%3d=%-6s", loc, e.data);
     41     return 0;
     42 }
     43 
     44 //构造一个空的线性链表L
     45 static int InitList(LinkList *L)
     46 {
     47     if(L==NULL){
     48         return -1;
     49     }
     50     Link p = (Link)malloc(sizeof(struct LNode));
     51     memset(p->e.data, 0, sizeof(p->e.data));
     52     p->next = p;
     53     L->len = 0;
     54     L->head = L->tail = p;
     55     return 0;
     56 }
     57 
     58 //返回p指示线性链表L中第i个结点的位置并返回0 i值不合法时返回-1
     59 static int LocatePos(LinkList *L, int i, Link *p)
     60 {
     61     if(L==NULL || p==NULL){
     62         return -1;
     63     }
     64     *p=L->head;
     65     int index = 0;
     66     while((index<L->len) && (*p != L->tail)){
     67         (*p) = (*p)->next;
     68         index +=1;
     69         if(index == i)
     70             break;
     71     }
     72     return (index==i)?0:-1;
     73 }
     74 
     75 //创建一个值为e的结点, 其地址为p; 成功则返回0, 失败就返回-1
     76 static int MakeNode(Link *p, ElemType e)
     77 {
     78     if(p==NULL){
     79         return -1;
     80     }
     81     if(((*p) = (Link)malloc(sizeof(struct LNode))) == NULL){
     82         return -1;
     83     }
     84     (*p)->next = NULL;
     85     (*p)->e = e;
     86     return 0;
     87 }
     88 
     89 //已知h指向线性链表的头结点,将s所指结点插入在第一个结点之前
     90 static int InsFirst(Link *h, Link *s)
     91 {
     92     if(h==NULL || s==NULL){
     93         return -1;
     94     }
     95     if(*h == NULL || *s == NULL){
     96         return -1;
     97     }
     98     (*s)->next = (*h)->next;
     99     (*h)->next = (*s);
    100     return 0;
    101 }
    102 
    103 //在带头结点的单链线性表L的第i个元素之前插入元素e
    104 static int ListInsert_L(LinkList *L, int i, ElemType e)
    105 {
    106     Link h = NULL;
    107     Link p = NULL;
    108     if(LocatePos(L, i-1, &h)<0){
    109         //i值不合法
    110         return -1;
    111     }
    112     if(MakeNode(&p, e)<0){
    113         //结点存储分配失败
    114         return -1;
    115     }
    116     //对于从第i个结点开始的链表,第i-1个结点是它的头结点
    117     InsFirst(&h, &p);
    118     //如果是在链表的最后一个结点上插入, 那么和改变链表的尾结点指针
    119     if(L->tail == h){
    120         p->next = L->head;
    121         L->tail = p;
    122     }
    123     //链表长度+1
    124     L->len += 1;
    125     return 0;
    126 }
    127 
    128 //创建一个长度为n的带头结点的单项链表L
    129 static int CreateList(LinkList *L, int n, char note[])
    130 {
    131     printf("创建一个长度为%d的带头结点的单向线性链表%s!
    ", n, note);
    132     if(L==NULL){
    133         return -1;
    134     }
    135     if(InitList(L)<0){
    136         return -1;
    137     }
    138     ElemType e;
    139     int i = 0;
    140     for(i=1; i<=n; i++){
    141         printf("输入第%d个元素:", i);
    142         scanf("%s[^\n]", e.data);
    143         if(ListInsert_L(L, i, e)<0){
    144             return -1;
    145         }
    146     }
    147 }
    148 
    149 //返回链表L的头结点
    150 static Link GetHead(LinkList *L){
    151     if(L==NULL){
    152         return NULL;
    153     }
    154     return L->head;
    155 }
    156 
    157 //返回链表L中结点p的后继
    158 static Link NextPos(LinkList *L, Link p)
    159 {
    160     if(L == NULL || p==NULL){
    161         return NULL;
    162     }
    163     return p->next;
    164 }
    165 
    166 //返回结点p中的数据元素
    167 static  ElemType GetCurElem(Link p)
    168 {
    169     return p->e;
    170 }
    171 
    172 //释放结点p
    173 static void FreeNode(Link p)
    174 {
    175     if(p)
    176         free(p);
    177     return;
    178 }
    179 
    180 //将指针s所指的一串结点连接到线性链表L的最后一个结点
    181 static int Append(LinkList *L, Link *s)
    182 {
    183     if(L == NULL || s==NULL || *s==NULL){
    184         return -1;
    185     }
    186     L->tail->next = (*s);
    187     Link p = *s;
    188     Link t = p;
    189     int count = 0;
    190     while(p){
    191         count += 1;
    192         t = p;
    193         p = p->next;
    194     }
    195     L->len += count;
    196     t->next = L->head;
    197     L->tail = t;
    198     return 0;
    199 }
    200 
    201 //已知h指向线性链表的头结点,删除链表中的第一个结点并以求返回
    202 static int DelFirst(Link *h, Link *q)
    203 {
    204     if(h==NULL || q==NULL){
    205         return -1;
    206     }
    207     if(*h == NULL || *q == NULL){
    208         return -1;
    209     }
    210     (*q) = (*h)->next;
    211     (*h)->next = (*q)->next;
    212     (*q)->next = NULL;
    213     return 0;
    214 }
    215 
    216 //已知单链线性表La和Lb的元素按值非递减排列
    217 //归并La和Lb得到新的单链线性表Lc  Lc的元素也按值非递减排列
    218 static int MergeList_L(LinkList *La, LinkList *Lb, LinkList *Lc, int (*compare)(ElemType,ElemType),const char note[])
    219 {
    220     printf("%s
    ", note);
    221     if(InitList(Lc)<0){
    222         //存储空间分配失败
    223         return -1;
    224     }
    225     Link ha = GetHead(La);//ha指向La的头结点
    226     Link hb = GetHead(Lb);//hb指向Lc的头结点
    227     if(ha==NULL || hb==NULL){
    228         return -1;
    229     }
    230     Link pa = NextPos(La, ha);//pa指向La中第一个结点
    231     Link pb = NextPos(Lb, hb);//pb指向Lb中第一个结点
    232     Link p;
    233 
    234     ElemType a;
    235     ElemType b;
    236 
    237     Link q;
    238     while(pa && pb){
    239         //La和Lb均非空
    240         //a和b为两表中当前比较元素
    241         a = GetCurElem(pa);
    242         b = GetCurElem(pb);
    243         if(compare(a, b)<=0){//a<=b
    244            DelFirst(&ha, &q);
    245            Append(Lc, &q);
    246             if(pa == La->tail){
    247                 pa = NULL;
    248                 break;
    249             }
    250            pa = NextPos(La, ha);
    251         }else{//a>b
    252             DelFirst(&hb, &q);
    253             Append(Lc, &q);
    254             if(pb == Lb->tail){
    255                 pb = NULL;
    256                 break;
    257             }
    258             pb = NextPos(Lb, hb);
    259         }
    260     }
    261     if(pa){
    262         //链接La中剩余结点
    263         p = pa;
    264         while(p){
    265             if(p == La->tail){
    266                 p->next = NULL;
    267                 break;
    268             }
    269             p = p->next;
    270         }
    271         Append(Lc, &pa);
    272     }else{
    273         //链接Lb中剩余结点
    274         p = pb;
    275         while(p){
    276             if(p == Lb->tail){
    277                 p->next = NULL;
    278                 break;
    279             }
    280             p = p->next;
    281         }
    282         Append(Lc, &pb);
    283     }
    284     //释放La和Lb的头结点
    285     FreeNode(ha);
    286     FreeNode(hb);
    287     return 0;
    288 }
    289 
    290 /*
    291  * 将元素a和b转换成整数a和整数b
    292  * 返回-1:整数a > 整数b
    293  * 返回0:整数a = 整数b
    294  * 返回1:整数a < 整数b
    295  */
    296 static int compare(ElemType a, ElemType b)
    297 {
    298     int i_a = atoi(a.data);
    299     int i_b = atoi(b.data);
    300     if(i_a<i_b){
    301         return -1;
    302     }else if(i_a == i_b){
    303         return 0;
    304     }else{
    305         return 1;
    306     }
    307 }
    308 
    309 int main(int argc, char *argv[])
    310 {
    311     LinkList La;    //3,5,8,11
    312     LinkList Lb;    //2,6,8,9,11,15,20
    313     if((CreateList(&La, 4, "La")<0) || (ListTraverse(La, print, "La")<0)){
    314         return -1;
    315     }
    316     if((CreateList(&Lb, 7, "Lb")<0) || (ListTraverse(Lb, print, "Lb")<0)){
    317         return -1;
    318     }
    319     LinkList Lc;
    320     if((MergeList_L(&La, &Lb, &Lc, compare, "归并La和Lb到Lc!")<0) || (ListTraverse(Lc, print, "Lc")<0)){
    321         return -1;
    322     }
    323     return 0;
    324 }
    带头结点的单项动态链表

    代码运行(带头结点的单向动态链表)

    /home/lady/CLionProjects/untitled/cmake-build-debug/untitled
    创建一个长度为4的带头结点的单向线性链表La!
    输入第1个元素:3
    输入第2个元素:5
    输入第3个元素:8
    输入第4个元素:11
    遍历线性表La:  1=3       1=5       1=8       1=11    
    创建一个长度为7的带头结点的单向线性链表Lb!
    输入第1个元素:2
    输入第2个元素:6
    输入第3个元素:8
    输入第4个元素:9
    输入第5个元素:11
    输入第6个元素:15
    输入第7个元素:20
    遍历线性表Lb:  1=2       1=6       1=8       1=9       1=11      1=15      1=20    
    归并La和Lb到Lc!
    遍历线性表Lc:  1=2       1=3       1=5       1=6       1=8       1=8       1=9       1=11      1=11      1=15      1=20    
    
    Process finished with exit code 0

    代码实现(静态单链表):

      1 //
      2 // Created by lady on 19-1-27.
      3 //
      4 
      5 #include <stdio.h>
      6 #include <stdlib.h>
      7 #include <string.h>
      8 
      9 //---------------线性表的静态单链表存储结构-----------
     10 #define MAXSIZE 12  //链表的最大长度
     11 typedef struct ElemType{
     12     char data[10];
     13 }ElemType;
     14 typedef struct{
     15     ElemType e;
     16     int cur;
     17 }component,SLinkList[MAXSIZE];
     18 
     19 /*
     20  * 依次打印静态链表space中的数据
     21  */
     22 static void Debug_Print(SLinkList space, char note[])
     23 {
     24     printf("%s
    ", note);
     25     int i = 0;
     26     for(i=0; i<MAXSIZE; i++){
     27         printf("	index %-5d[data:%-5s,cur:%-2d]
    ", i, space[i].e.data, space[i].cur);
     28     }
     29 }
     30 
     31 /*
     32  * 将一维数组space中各分量链成一个备用链表,space[0].cur为头指针, “0”表示空指针。
     33  */
     34 static void InitSpace_SL(SLinkList space)
     35 {
     36     int i = 0;
     37     for(i=0; i<MAXSIZE-1; ++i){
     38         memset(space[i].e.data, 0, sizeof(space[i].e.data));
     39         space[i].cur = i+1;
     40     }
     41     memset(space[MAXSIZE-1].e.data, 0, sizeof(space[MAXSIZE-1].e.data));
     42     space[MAXSIZE-1].cur = 0;
     43     return ;
     44 }
     45 
     46 /*
     47  * 如果备用空间链表非空,则返回分配的结点下标,否则返回0
     48  */
     49 static int Malloc_SL(SLinkList space)
     50 {
     51     int i = 0;
     52     i = space[0].cur;
     53     if(space[0].cur)
     54         space[0].cur = space[i].cur;
     55     return i;
     56 }
     57 
     58 /*
     59  *  将下标为k的空闲结点回收到备用链表。
     60  */
     61 static int Free_SL(SLinkList space, int k)
     62 {
     63     space[k].cur = space[0].cur;
     64     space[0].cur = k;
     65     return 0;
     66 }
     67 
     68 /*
     69  * 依次输入集合A和B的元素,在一维数组space中建立表示集合 (A-B)U(B-A)的静态链表,S为其头指针。
     70  * 假设备用空间够大,space[0].cur为备用空间的头指针
     71  */
     72 static void difference(SLinkList space, int *S)
     73 {
     74     printf("用静态链表算集合(A-B)U(B-A):
    ");
     75     InitSpace_SL(space); //将space整个初始化成备用空间
     76     (*S) = Malloc_SL(space);//生成S的头结点
     77     int r = *S;//r始终指向静态链表S的最后一个元素。
     78     int m, n;
     79     int i, j;
     80     char str[128] = {0};
     81     printf("step1	:依次输入A和B集合的元素个数(m,n):");
     82     scanf("%d,%d[^\n]", &m, &n);
     83     printf("step2.1	:依次输入A中的元素到集合S:
    ");
     84     for(j=1; j<=m; ++j){
     85         i = Malloc_SL(space);
     86         printf("	输入A中第%d/%d个元素:", j, m);
     87         scanf("%s[^\n]", space[i].e.data);
     88         //插入到表尾巴
     89         space[r].cur = i;
     90         r = i;
     91     }
     92     space[r].cur = 0;
     93     Debug_Print(space, "step2.2	:创建集合A后的集合S值");
     94 
     95     printf("step3	:依次输入B中的元素,同时查找S表,如果已经存在则从S中删除之,否则加入到S!
    ");
     96     ElemType b;
     97     int p;
     98     int k;
     99     for(j=1; j<=n; ++j){
    100         memset(b.data, 0, sizeof(b.data));
    101         printf("	输入B中第%d/%d个元素:", j, n);
    102         scanf("%s[^\n]", b.data);
    103         p = (*S);
    104         k = space[p].cur; //k指向集合A中第一个结点
    105         while(k!=space[r].cur && strncmp(space[k].e.data, b.data, sizeof(b.data))){
    106             //在当前表中查找
    107             p = k;
    108             k = space[k].cur;
    109         }
    110         if(k == space[r].cur){
    111             //当前表中不存在该元素, 插入在r所值结点后,且r的位置不变。
    112             i = Malloc_SL(space);
    113             space[i].e = b;
    114             space[i].cur = space[r].cur;
    115             space[r].cur = i;
    116             snprintf(str, sizeof(str), "step3.1	:元素%s在S中不存在,插入之!",b.data);
    117             Debug_Print(space, str);
    118         }else{
    119             //该元素已在表中,则删除之
    120             space[p].cur = space[k].cur;
    121             Free_SL(space, k);
    122             if(r == k){
    123                 //如果删除的是r所指结点,则需修改尾指针。
    124                 r = p;
    125             }
    126             snprintf(str, sizeof(str), "step3.1	:元素%s在S中存在,删除之!",b.data);
    127             Debug_Print(space, str);
    128         }
    129     }
    130 }
    131 
    132 int main(int argc, char *argv[])
    133 {
    134     SLinkList space;
    135     int s;
    136     //求(A-B)U(B-A)
    137     difference(space, &s);
    138     return 0;
    139 }
    静态链表

    代码运行(静态单链表):

    /home/lady/CLionProjects/untitled/cmake-build-debug/untitled
    用静态链表算集合(A-B)U(B-A):
    step1    :依次输入A和B集合的元素个数(m,n):6,4
    step2.1    :依次输入A中的元素到集合S:
        输入A中第1/6个元素:c
        输入A中第2/6个元素:b
        输入A中第3/6个元素:e
        输入A中第4/6个元素:g
        输入A中第5/6个元素:f
        输入A中第6/6个元素:d
    step2.2    :创建集合A后的集合S值
        index 0    [data:     ,cur:8 ]
        index 1    [data:     ,cur:2 ]
        index 2    [data:c    ,cur:3 ]
        index 3    [data:b    ,cur:4 ]
        index 4    [data:e    ,cur:5 ]
        index 5    [data:g    ,cur:6 ]
        index 6    [data:f    ,cur:7 ]
        index 7    [data:d    ,cur:0 ]
        index 8    [data:     ,cur:9 ]
        index 9    [data:     ,cur:10]
        index 10   [data:     ,cur:11]
        index 11   [data:     ,cur:0 ]
    step3    :依次输入B中的元素,同时查找S表,如果已经存在则从S中删除之,否则加入到S!
        输入B中第1/4个元素:a
    step3.1    :元素a在S中不存在,插入之!
        index 0    [data:     ,cur:9 ]
        index 1    [data:     ,cur:2 ]
        index 2    [data:c    ,cur:3 ]
        index 3    [data:b    ,cur:4 ]
        index 4    [data:e    ,cur:5 ]
        index 5    [data:g    ,cur:6 ]
        index 6    [data:f    ,cur:7 ]
        index 7    [data:d    ,cur:8 ]
        index 8    [data:a    ,cur:0 ]
        index 9    [data:     ,cur:10]
        index 10   [data:     ,cur:11]
        index 11   [data:     ,cur:0 ]
        输入B中第2/4个元素:b
    step3.1    :元素b在S中存在,删除之!
        index 0    [data:     ,cur:3 ]
        index 1    [data:     ,cur:2 ]
        index 2    [data:c    ,cur:4 ]
        index 3    [data:b    ,cur:9 ]
        index 4    [data:e    ,cur:5 ]
        index 5    [data:g    ,cur:6 ]
        index 6    [data:f    ,cur:7 ]
        index 7    [data:d    ,cur:8 ]
        index 8    [data:a    ,cur:0 ]
        index 9    [data:     ,cur:10]
        index 10   [data:     ,cur:11]
        index 11   [data:     ,cur:0 ]
        输入B中第3/4个元素:n
    step3.1    :元素n在S中不存在,插入之!
        index 0    [data:     ,cur:9 ]
        index 1    [data:     ,cur:2 ]
        index 2    [data:c    ,cur:4 ]
        index 3    [data:n    ,cur:8 ]
        index 4    [data:e    ,cur:5 ]
        index 5    [data:g    ,cur:6 ]
        index 6    [data:f    ,cur:7 ]
        index 7    [data:d    ,cur:3 ]
        index 8    [data:a    ,cur:0 ]
        index 9    [data:     ,cur:10]
        index 10   [data:     ,cur:11]
        index 11   [data:     ,cur:0 ]
        输入B中第4/4个元素:f
    step3.1    :元素f在S中存在,删除之!
        index 0    [data:     ,cur:6 ]
        index 1    [data:     ,cur:2 ]
        index 2    [data:c    ,cur:4 ]
        index 3    [data:n    ,cur:8 ]
        index 4    [data:e    ,cur:5 ]
        index 5    [data:g    ,cur:7 ]
        index 6    [data:f    ,cur:9 ]
        index 7    [data:d    ,cur:3 ]
        index 8    [data:a    ,cur:0 ]
        index 9    [data:     ,cur:10]
        index 10   [data:     ,cur:11]
        index 11   [data:     ,cur:0 ]
    
    Process finished with exit code 0
  • 相关阅读:
    多线程编程(6) 从 CreateThread 说起[续四]
    多线程编程(7) 从 CreateThread 说起[续五]
    我最喜欢的邮件客户端软件IncrediMail Xe
    [公告]博客园建立了“专家区”
    [新功能]文章档案
    Lucene.Net的语言处理包中Lucene.Net.Analysis.Cn的Bug
    [好消息]博客园与博文视点、第二书店合作推出“读书心得区”
    推荐一篇有关GC的文章
    [小技巧]在NTFS分区中复制文件的同时如何复制权限
    ShartPoin无法创建门户网站的问题
  • 原文地址:https://www.cnblogs.com/aimmiao/p/10391917.html
Copyright © 2011-2022 走看看