双向链表的实现
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 }
以上是关于双向链表的实现的主要内容,如果未能解决你的问题,请参考以下文章