先上代码:双向链表的基本操作
#include#include #include #define overflow 1 typedef struct node_{ int data; struct node_ *next; struct node_ *precursor; }Node,*node; void initList(node &l); void insertNode(node &l,int n); void clearList(node &l); void desList(node &l); bool listEmpty(node &l); int getElement(node &l,int i); int locateElement(node &l,int e); int priorElement(node &l,int e); int nextElement(node &l,int e); void deleteNode(node &l,int e); void test(); //建立链表 void initList(node &l){ l=(node)malloc(sizeof(Node)); l->next=NULL; l->precursor=NULL; if (!l){ exit(overflow); } } //插入元素 void insertElement(node &l,int n,int g){ node p,q; p=l; for (int i = 0; i < g; i ++) { p = p->next; if (p == NULL) { printf("The position %d is beyond the scope of the list.", g); return; } } q = (node)malloc(sizeof(Node)); q->data = g; q->next = p->next; p->next = q; q->precursor=p; q->next->precursor=q; } //尾插法 void insertNode(node &l,int n){ if(n<0){ printf("输入的n不合法n"); exit(overflow); } node last=NULL; last=l; for (int i=0;i data); p->next=NULL; p->precursor=NULL; last->next=p; p->precursor=last; last=p; } } //打印链表 void printList(node &l) { if (!l) { printf("链表不存在"); exit(overflow); } printf("打印链表:"); for (node p=l->next;p;p=p->next) { printf("%d ",p->data); } printf("n"); } //清空链表 void clearList(node &l) { node p=l->next; node q=p; while(p){ q=p->next; free(p); p=NULL; p=q; } l->next=NULL; } //销毁链表 void desList(node &l){ node p=l; node q=p; while(p->next){ q=p->next; free(p); p=NULL; p->next=q->next; } l=NULL; printf("链表已销毁");} //检查链表是否为空 bool listEmpty(node &l) { if (l->next) { return true; } else { return false; } } //返回链表第i个的值 int getElement(node &l,int i){ if (i<=0 || l->next==NULL){ printf("链表为空或i的值不合法"); exit(overflow); } node p=l; for (int q=0;qnext; } return p->data; } //返回与e值相同的元素位置 int locateElement(node &l,int e){ int i=0; for (node p=l->next;p;p=p->next) { i++; if (p->data==e){ return i; } } return 0; } //返回指定元素的前驱 int priorElement(node &l,int e){ for (node p=l->next;p;p=p->next) { if (p->data==e){ return p->precursor->data; } } return 0; } //返回指定元素的后继 int nextElement(node &l,int e) { for (node p=l->next;p->next;p=p->next) { if (p->data==e){ return p->next->data; } } return 0; } //删除指定的结点 void deleteNode(node &l,int e){ node p=l; while(p->next) { if (p->next->data==e){ node q=p->next; p->next=p->next->next; free(q); q=NULL; } else p=p->next; } } void test(){ node l; initList(l); int n; scanf("%d",&n); insertNode(l,n); printList(l); bool r=listEmpty(l); printf("链表是否为空:%dn",r); int e; e=locateElement(l, 2); printf("该元素的位置:%dn",e); e=getElement(l,3); printf("某位置的元素:%dn",e); e=priorElement(l,e); printf("元素的前驱:%dn",e); e=nextElement(l,e); printf("元素后继:%dn",e); deleteNode(l,e); printf("删除指定元素后:"); printList(l); clearList(l); r=listEmpty(l); printf("清空链表后:"); printf("链表是否为空:%dn",r); desList(l); } int main(void) { test(); return 0; }
运行结果:
总结:
双向链表的相关操作还是比较简单。关键收获在于:这次再写双向链表的过程中依然出现了之前经常出现的问题---关于内存方面,这次看了好一些文章看完总算有种豁然开朗的感觉(以前内存方面确实学得太差了)
附上几篇好文章:C与C++关于*与&的传参解析 (baidu.com)
(26条消息) c中使用free()函数,指针仍然有地址?_小菜菜ovo的博客-CSDN博客



