【数据结构】除去线性表中的重复数字
题目:写一个算法将单链表中值重复的结点删除,使所得的结果表中各结点值均不相同。
刚看到这个题目给我第一个思路是冒泡排序,可以利用冒泡排序的两层循环找出相同的结点,然后free掉。第一层循环是控制循环的次数,第二层循环是控制第n个值和后面值的比较的次数。循环方面还比较好做,在删除结点的时候碰到了一些问题。因为删除结点的时候就相当于把指针指向的空间释放了,这个时候指针链就会断开,不再是一个连续的链表。为了连接链表,还需要额外定义一个变量,来记录释放结点的前一个节点,然后才可以把释放结点的前一个结点连接到释放结点的后一个结点(有点绕口,看代码就知道了)。
线性表的定义,和创建线性表,读取线性表的代码就不解释了,本人在【数据结构】顺序线性表的构造和存储数据中有写过;
现在直接贴上核心函数:
1 //除去重复的值 2 void deldou(LNode *l) 3 { 4 LNode *p,*h,*temp,*q; 5 int i,j,n; 6 n = 0; 7 h = l->next; 8 p = h->next; 9 while(h->next !=NULL) //第一层循环控制循环的次数 10 { 11 while(p!=NULL) //第二层循环控制第i个数对比的次数 12 { 13 if(h->x == p->x) 14 { 15 temp = p->next; //为了使释放p的时候p所指向的指针不丢失, 16 free(p); //释放p对应的内存 17 p = temp; 18 q->next = p; //链接线性表,把释放结点的前一个结点和后一个结点连接到一起 19 } 20 else 21 { 22 q = p; //得到上一个p节点,为了链接释放结点的后一结点。 23 p = p->next; 24 } 25 } 26 h = h->next; 27 p = h->next; 28 } 29 }
代码中定义了*temp,*q;都是为了不让链表断裂而创建的;q记录了释放掉的p的上一个结点,temp记录了释放的p的下一个结点,然后把他们连在一起,整个线性表就不会断裂了;
附上完整代码:
View Code
1 #include<stdio.h> 2 #include<stdlib.h> 3 4 typedef struct node 5 { 6 int x; 7 struct node *next; 8 }LNode; 9 10 11 //函数声明 12 LNode *create_l(); 13 void out_l(LNode *l); 14 void deldou(LNode *l); 15 16 //主函数 17 void main() 18 { 19 LNode *l; 20 l = create_l(); 21 out_l(l); 22 deldou(l); 23 out_l(l); 24 } 25 26 //除去重复的值 27 void deldou(LNode *l) 28 { 29 LNode *p,*h,*temp,*q; 30 int i,j,n; 31 n = 0; 32 h = l->next; 33 p = h->next; 34 while(h->next !=NULL) //第一层循环控制循环的次数 35 { 36 while(p!=NULL) //第二层循环控制第i个数对比的次数 37 { 38 if(h->x == p->x) 39 { 40 temp = p->next; //为了使释放p的时候p所指向的指针不丢失, 41 free(p); //释放p对应的内存 42 p = temp; 43 q->next = p; //链接线性表,把释放结点的前一个结点和后一个结点连接到一起 44 } 45 else 46 { 47 q = p; //得到上一个p节点,为了链接释放结点的后一结点。 48 p = p->next; 49 } 50 } 51 h = h->next; 52 p = h->next; 53 } 54 } 55 56 //创建链表 57 LNode *create_l() 58 { 59 LNode *h,*p,*l; 60 int x,n,i; 61 h = (LNode *)malloc(sizeof(LNode)); 62 h->next = NULL; 63 p = h; 64 printf("请输入创建链表的长度:"); 65 scanf("%d",&n); 66 for(i = 0; i < n; i++) 67 { 68 printf("请输入第%d个值:",i + 1); 69 scanf("%d",&x); 70 l = (LNode *)malloc(sizeof(LNode)); 71 l->x = x; 72 l->next = NULL; 73 p->next = l; 74 p = l; 75 } 76 return(h); 77 } 78 79 //读取链表 80 void out_l(LNode *l) 81 { 82 LNode *p; 83 p = l; 84 p = p->next; 85 while(p!=NULL) 86 { 87 printf("%5d",p->x); 88 p = p->next; 89 } 90 printf("\n"); 91 }