线性表->链式存储->线形链表(单链表)

文字描述:

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

 

示意图:

 

算法分析:

在单链表中插入和删除元素时,主要是改变指针的值,其时间复杂度为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:\n", 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!\n",i);
 54         }
 55         p = p->next;
 56     }
 57     printf("\n");
 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("\n");
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\n", location, e.data);
233     ListTraverse_L(L, printE, "init:");
234     printf("\n");
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\n", location, e.data);
240     printf("\n");
241 
242     printf("Merge LA and LB to  LC!\n");
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("\n");
 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", 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\n", 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\n", note);
 25     int i = 0;
 26     for(i=0; i<MAXSIZE; i++){
 27         printf("\tindex %-5d[data:%-5s,cur:%-2d]\n", 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):\n");
 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\t:依次输入A和B集合的元素个数(m,n):");
 82     scanf("%d,%d[^\\n]", &m, &n);
 83     printf("step2.1\t:依次输入A中的元素到集合S:\n");
 84     for(j=1; j<=m; ++j){
 85         i = Malloc_SL(space);
 86         printf("\t输入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\t:创建集合A后的集合S值");
 94 
 95     printf("step3\t:依次输入B中的元素,同时查找S表,如果已经存在则从S中删除之,否则加入到S!\n");
 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("\t输入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\t:元素%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\t:元素%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

 

posted on 2019-02-17 17:27  LiveWithACat  阅读(322)  评论(0编辑  收藏  举报