双向链表的实现

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了双向链表的实现相关的知识,希望对你有一定的参考价值。

   主要功能如下:
      1.利用尾插法建立一个双向循环链表。
      2.遍历双向循环链表。
      3.实现双向循环链表中删除一个指定元素。
      4.在非递减有序双向循环链表中实现插入元素e仍有序算法。
      5.判断双向循环链表中元素是否对称若对称返回1否则返回0。
      6.设元素为正整型,实现算法把所有奇数排列在偶数之前。
      7.在主函数中设计一个简单的菜单调试上述算法。
  1 #include "stdio.h"
  2 #include "stdlib.h"
  3 typedef int elemtype;
  4 
  5 typedef struct lnode    //定义结点类型
  6 {
  7  elemtype data;
  8  struct lnode *next;
  9  struct lnode *prior;
 10 }lnode,*linklist;
 11 
 12 int initlist(linklist &L)   //初始化单链表
 13 {
 14  L=(linklist)malloc(sizeof(lnode));   //表头附加结点
 15  if(!L) exit(-2);
 16  L->next=L;
 17  L->prior=L;
 18  return 1;                 
 19 }//初始化了一个空表
 20 
 21 void createlist(linklist &L)  //尾插法生成双向循环链表
 22 {
 23  int x;
 24  linklist q=L;
 25  printf("请输入要插入元素的值(输入0结束):\n");
 26  scanf("%d",&x);
 27  while(x){
 28   linklist p=(linklist)malloc(sizeof(lnode));
 29   p->data=x;
 30   q->next=p;
 31   L->prior=p;
 32   p->prior=q;
 33   p->next=L;
 34   q=p;
 35   scanf("%d",&x);
 36  }          
 37 }
 38 
 39 void shuchulist(linklist &L)  //遍历有头结点的双向循环链表
 40 {
 41  linklist p=L->next;
 42  while(p->next!=L){
 43   printf("%4d",p->data);
 44   p=p->next;
 45  }
 46  printf("%4d",p->data);
 47  printf("\n");
 48 }
 49 int lengthlist(linklist L){//通过链表的遍历来统计长度
 50  linklist p=L->next;
 51  int count=0;
 52  while(p!=L){
 53   p=p->next;
 54   count++;
 55  }
 56  return count;
 57 }
 58 
 59 int listdelete_i(linklist &L,int i){//删除带头结点的双向循环链表中第i个元素
 60  linklist p=L; 
 61  int j=0;
 62  if(i>lengthlist(L)){
 63   return 0;
 64  }
 65  while(j<i){//寻找第i个结点,并令p指向此结点
 66   p=p->next; ++j;
 67  }
 68  p->prior->next=p->next;//删除结点p
 69  free(p);//释放结点p
 70  return 1;
 71 }
 72 int listdelete_x(linklist &L,elemtype x){//删除值为x的元素
 73  linklist p=L->next,q;
 74  int i=0;
 75  while(p!=L){
 76   if(p->data==x){
 77    q=p->next;
 78    p->next->prior=p->prior;
 79    p->prior->next=p->next;
 80    free(p);
 81    p=q;
 82    ++i;
 83   }
 84   else
 85    p=p->next;
 86  }
 87  return i;
 88 }
 89 
 90 void paixu(linklist L){//将链表排成非递减链表
 91  int t;
 92  linklist p;
 93  for(int i=1;i<lengthlist(L);i++){
 94   p=L->next;
 95   for(int j=0;j<lengthlist(L)-i;j++){
 96    if(p->data>p->next->data){
 97     t=p->data;
 98     p->data=p->next->data;
 99     p->next->data=t;
100    }
101    p=p->next;
102   }
103  }
104 }
105 void linklistinsert(linklist &L,elemtype e){//在非递减有序双向循环链表中实现插入元素e仍有序
106  linklist p=L->next;
107  linklist q=(linklist)malloc(sizeof(lnode));
108  q->data=e;
109  if(L->prior->data<e){//把元素e 插到最后
110   L->prior->next=q;
111   q->prior=L->prior;
112   q->next=L;
113   L->prior=q;
114  }else{
115   while(p->data<e){//找到第一个大于或等于e的元素
116    p=p->next;
117   }
118   //把e插到第一个大于或等于它的元素之前
119   p->prior->next=q;
120   q->prior=p->prior;
121   q->next=p;
122   p->prior=q;
123  }
124 }
125 
126 int panduan(linklist L){//判断双向循环链表中元素是否对称
127  linklist p=L->next,q=L->prior;
128  if(lengthlist(L)%2){
129   while(p->data==q->data&&p!=q){
130    p=p->next;q=q->prior;
131   }
132   if(q==p)
133    return 1;
134   else
135    return 0;
136  }else{
137   while(p->data==q->data&&p->next!=q){
138    p=p->next;q=q->prior;
139   }
140   if(p->data==q->data)
141    return 1;
142   else
143    return 0;
144  }
145 }
146 
147 void jioushu(linklist L){//把链表中奇数放到偶数之前
148  linklist p=L->next,q,s;
149  s=L->prior;
150  while(p!=s){
151   if(p->data%2)
152    p=p->next;
153   else{
154    q=p->next;
155    p->prior->next=p->next;  p->next  ->prior=p->prior;//把p从链表中取出
156    p->prior=L->prior;
157    L->prior->next=p;
158    p->next=L;
159    L->prior=p;
160    p=q;
161   }
162  }
163 }
164 
165 int main()
166 {
167  linklist La;
168  int menu,flag,i,x,c;
169  do{
170   printf("1.利用尾插法建立双向循环链表链表\n");
171   printf("2.遍历双向循环链表\n");
172   printf("3.双向循环链表中删除一个指定元素\n");
173   printf("4.在非递减有序双向循环链表中实现插入元素e仍有序\n");
174   printf("5.判断双向循环链表中元素是否对称若对称返回1否则返回0\n");
175   printf("6.设元素为正整型,实现算法把所有奇数排列在偶数之前\n");
176   printf("0.退出\n");
177   printf("\n请输入所选菜单(0-6): ");
178   scanf("%d",&menu);
179   switch(menu){
180   case 1: initlist(La);createlist(La);break;
181   case 2: printf("链表中的元素为:\n");shuchulist(La);break;
182   case 3: printf("请选择删除方式:1 删除值为x的结点  2 删除第i个结点  ");
183    scanf("%d",&c);
184    if(c==1){
185     printf("请输入要删除元素的值: ");
186     scanf("%d",&x);
187     flag=listdelete_x(La,x);
188     if(flag){
189      printf("删除成功!\n");
190      printf("删除后的链表为:\n");
191      shuchulist(La);
192     }else
193      printf("删除失败!\n");
194    }else if(c==2){
195     printf("请输入要删除的位置: ");
196     scanf("%d",&i);
197     flag=listdelete_i(La,i);
198     if(flag){
199      printf("删除成功!\n");
200      printf("删除后的链表为:\n");
201      shuchulist(La);
202     }else
203      printf("删除失败!\n");
204    }
205    break;
206   case 4: printf("把原始链表初始化为非递减有序列表为:\n");
207    paixu(La);
208    shuchulist(La);
209    printf("请输入要插入的元素的值: ");
210    scanf("%d",&x);
211    linklistinsert(La,x);
212    printf("插入后的链表为:\n");
213    shuchulist(La);
214    break;
215   case 5: flag=panduan(La); 
216    if(flag)
217      printf("链表对称!\n");
218    else
219     printf("链表不对称!\n");
220    break;
221   case 6: printf("排列之前为:\n");
222    shuchulist(La);
223    jioushu(La); 
224    printf("排列之后为:\n");
225    shuchulist(La); break;
226   case 0: exit(0);
227   }
228  }while(menu);
229   return 0;230 }

 

以上是关于双向链表的实现的主要内容,如果未能解决你的问题,请参考以下文章

链表的java实现(单向双向链表,单向链表的反转)

双向链表的实现(双向链表与单向链表的简单区别联系和实现)

双向链表的实现(双向链表与单向链表的简单区别联系和实现)

OC中双向链表的实现

代码模板实现双向链表的去重拼接合并排序

双向链表的实现