数据结构--双向循环链表C实现
2016-04-19 13:43
751 查看
双向链表的优点是可以向前后两个方向遍历,而单链表和循环链表,如果要对某一个元素进行操作,必须找到该元素的前一结点;而双链表就不需要,因为它可以向前遍历,找到前一结点修改它的后缀,同理可以修改后一结点的前缀。
本文代码没有使用哨兵结点实现。
学习总结:
先看下面的代码:
看似程序没有问题,但是总是纠结为什么得不到正确的结果。深入探讨发现,地址的传递并没有问题,只是地址指向的数据不见了。还是学艺不精啊0.0。原来str数组定义为局部变量,随着函数fuc的结束而结束。所以ch接收到的字符串的首地址已经没有指向想要的字符串了。
一朝被蛇咬,十年怕井绳啊!
于是乎我觉得下面的代码也有问题:
一个链表的初始化,没错,它是在子函数里面的进行的。但是为什么它的内存空间没有杯释放呢?
原来是malloc函数的原因,该函数主动申请一段内存,内存就不会被系统显性地释放,需要主动调动free函数释放内存0.0。
本文代码没有使用哨兵结点实现。
#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。
相关文章推荐
- 如何组织构建多文件 C 语言程序(二)
- [C/C++]反转链表
- 如何写好 C main 函数
- C#数据结构之顺序表(SeqList)实例详解
- C#实现基于链表的内存记事本实例
- Lua和C语言的交互详解
- Lua教程(七):数据结构详解
- 解析从源码分析常见的基于Array的数据结构动态扩容机制的详解
- C#数据结构之队列(Quene)实例详解
- C#数据结构揭秘一
- C#数据结构之单链表(LinkList)实例详解
- 关于C语言中参数的传值问题
- 简要对比C语言中三个用于退出进程的函数
- 深入C++中API的问题详解
- 基于C语言string函数的详解
- C语言中fchdir()函数和rewinddir()函数的使用详解
- C语言内存对齐实例详解
- C语言编程中统计输入的行数以及单词个数的方法
- C语言自动生成enum值和名字映射代码
- 使用C语言判断英文字符大小写的方法