数据结构--双向循环链表C实现
来源:互联网 发布:小说站源码 编辑:程序博客网 时间:2024/04/20 04:42
双向链表的优点是可以向前后两个方向遍历,而单链表和循环链表,如果要对某一个元素进行操作,必须找到该元素的前一结点;而双链表就不需要,因为它可以向前遍历,找到前一结点修改它的后缀,同理可以修改后一结点的前缀。
本文代码没有使用哨兵结点实现。
#include <stdio.h>#include <stdlib.h>typedef int Mt;typedef struct Node{ Mt data; struct Node *next; struct Node *prior;}Dlist;Dlist *CurPosition;Dlist* init(){ Dlist *head=NULL,*p ,*p1; int n; printf("输入数据数量:\n"); scanf("%d",&n); if(n>0) { p = (Dlist*)malloc(sizeof(Dlist)); if(p == NULL){ printf("内存申请失败!\n"); return NULL; } if(head==NULL) { head = p; } scanf("%d",&p->data); p->next = p; p->prior = p; p1 = p; while (--n>0) { p= (Dlist*)malloc(sizeof(Dlist)); scanf("%d",&p->data); p1->next = p; p->next = p1; p->prior = p1; p1 = p; } p1->next = head; head->prior = p1; } CurPosition = head;//返回当前位置。 return head;}void printDlist(Dlist *head){ Dlist *h; h=head; if(head == NULL) { printf("该链表为空!\n"); }else { while(head!=NULL) { printf("%d ",head->data); head = head->next; if(head == h) break; } }}Dlist* deleteDlist(Dlist *head){ Dlist *h1,*h2; h1 = head; while(head!=NULL) { h2 = head; free(head); head = h2->next; if(h1==head) { printf("双向链表删除完成!\n"); break; } } return NULL;}int LengthDlist(Dlist *head){ int length =0; Dlist *h = head; while(head!=NULL) { length++; head = head->next; if(head == h) break; } return length;}Dlist* insertHead(Dlist* head,Mt num){ Dlist *p; p = (Dlist*)malloc(sizeof(Dlist)); if(p == NULL){ printf("内存申请失败!\n"); return head; } p->data = num; if(head == NULL) { p->next = p; p->prior = p; }else { p->next = head; p->prior = head->prior; head->prior->next = p; head->prior = p; } printf("插入成功!\n"); return CurPosition = p;}Dlist *Taildelete(Dlist *head){ Dlist* h; if(head==NULL) { printf("该链表为空,删除失败!\n"); return NULL; }else if(head == head->next) { free(head); return NULL;//如果只有一个结点,返回NULL }else { h=head->prior; head->prior = h->prior; h->prior->next = head; free(h); printf("删除尾部结点完成!\n"); } CurPosition = head->prior; return head;}Dlist* insertPosition(Dlist* head,int pos,Mt num){ int i; int len = LengthDlist(head); Dlist *p,*h=head; if(pos>len+1) { printf("插入位置超过链表长度!\n"); return head; }else if(head ==NULL) { p = (Dlist*)malloc(sizeof(Dlist)); if(p == NULL){ printf("内存申请失败!\n"); return head; } p->data = num; p->next = p; p->prior = p; return p; }else { p = (Dlist*)malloc(sizeof(Dlist)); if(p == NULL){ printf("内存申请失败!\n"); return head; } p->data =num; if(pos==1) { p->next = head; p->prior = head->prior; head->prior->next = p; head->prior = p; h = p; }else if(pos == LengthDlist(head)) { p->next = head; p->prior = head->prior; head->prior->next = p; head->prior = p; h = p; }else { for(i=2;i<pos;i++) { head = head->next; } p->next = head->next; p->prior = head; head->next->prior = p; head->next = p; CurPosition = p; } } return h;}Dlist* deletePosition(Dlist* head,int pos){ Dlist* h; if(head==NULL) { printf("该链表为空,删除第%d个位置的元素失败!\n",pos); return NULL; }else if(pos>LengthDlist(head) || pos<=0) { printf("删除位置超过链表长度!\n"); return head; }else if(LengthDlist(head)==1) { free(head); return NULL; } else if(pos == 1) { h = head->next; head->prior->next = head->next; h->prior = head->prior; free(head); }else if(pos == LengthDlist(head)) { h = head; head = head->prior; h->prior = head->prior; head->prior->next = h; free(head); }else { h = head; while(--pos) { head = head->next; } head->next->prior = head->prior; head->prior->next = head->next; CurPosition = head->next; free(head); } return h;}int getPosElement(Dlist *head) //获取当前操作的位置{ int Pos=1; if(head == CurPosition) { Pos = 1; }else { while(head!=CurPosition) { Pos++; head = head->next; } } return Pos;}int main(int argc, char *argv[]) { Dlist *Head=NULL; Dlist *CurPosition; int Len,Pos; Head = init(); //printDlist(Head); //Head = deleteDlist(Head); //Len = LengthDlist(Head); //printf("该链表长度为:%d\n",Len); //printf("从头部插入一个数:\n"); //Head = insertHead(Head,4); //printDlist(Head); //Head = Taildelete(Head); //Head = insertPosition(Head,3,8); Head = deletePosition(Head,2); printDlist(Head); Len = LengthDlist(Head); printf("该链表长度为:%d\n",Len); Pos = getPosElement(Head); printf("当前操作位置:%d\n",Pos); return 0;}
学习总结:
先看下面的代码:
#include <stdio.h>#include <stdlib.h>#include <string.h>/* run this program using the console pauser or add your own getch, system("pause") or input loop */char *fuc(char *s){ char str[20]=""; int i,j; for(i=strlen(s)-1,j=0;i>=0;i--,j++) { str[j]=s[i]; } return str;}int main(int argc, char *argv[]) { char *s = "hello world"; char *ch; ch = fuc(s); //将s指向的字符数组逆序并返回 puts(ch); printf("\n"); return 0;}
看似程序没有问题,但是总是纠结为什么得不到正确的结果。深入探讨发现,地址的传递并没有问题,只是地址指向的数据不见了。还是学艺不精啊0.0。原来str数组定义为局部变量,随着函数fuc的结束而结束。所以ch接收到的字符串的首地址已经没有指向想要的字符串了。
一朝被蛇咬,十年怕井绳啊!
于是乎我觉得下面的代码也有问题:
Rlist init(Rlist head) //建立哨兵结点{ Rlist p; p = (Rlist)malloc(sizeof(struct Node)); if(errMemory(p)) { head = p; p->next =NULL; return head; } return NULL;}
一个链表的初始化,没错,它是在子函数里面的进行的。但是为什么它的内存空间没有杯释放呢?
原来是malloc函数的原因,该函数主动申请一段内存,内存就不会被系统显性地释放,需要主动调动free函数释放内存0.0。
0 0
- 数据结构--双向循环链表C实现
- 数据结构的C实现_双向循环链表
- 数据结构--双向循环链表c语言实现
- 【数据结构】双向循环链表实现
- 数据结构通用双向循环链表实现
- 【数据结构】双向循环链表实现
- C/C++、JAVA 数据结构 :双向循环链表
- C语言实现双向循环链表
- c双向循环链表实现
- C语言实现双向循环链表
- C语言实现双向循环链表
- C语言实现双向循环链表
- C语言双向循环链表实现
- C语言实现双向循环链表
- 【C++】实现双向循环链表
- c语言实现双向循环链表
- 数据结构(C实现)------- 双向链表
- C实现通用数据结构--双向链表
- java 1.8 函数式编程
- BestCoder Round #80 1002
- Java设计模式之装饰器模式
- GIT 的常规操作
- hdu3709 数位dp
- 数据结构--双向循环链表C实现
- js实现上传图片及时预览
- 反射机制
- Oracle存儲過程-用JAVA調用總結
- Android studio 混淆proguard
- Android -- Sensor 简介
- x64 python3.4 + opencv3.1.0 + opencv_contrib_master
- 数据库中的join
- 电话面试总结(问的很细).md