Linux c 算法与数据结构--双向链表
来源:互联网 发布:淘宝直通车设置流程 编辑:程序博客网 时间:2024/05/16 01:12
最近一直在巩固C语言基础,写的一些文章主要也是当自己的学习笔记,肯定会出现一些小错误,或者内容比较初级,希望通过自己的努力写出一些高水平的博文!
链表是linux c中非常重要的数据结构,双向链表与单向链表的区别,是它每个节点有两个指针域,分别指向该节点的前一个节点与后一个节点;
而链表的操作主要是查询、插入、删除、遍历等,下面来看一个双向链表,主要是进行写小练习,加深印象!
代码如下:
Dlist.h
#ifndef DList_H#define DList_Htypedef int Item;typedef struct Node * PNode;typedef PNode Position;/*定义节点类型*/typedef struct Node{ Item data; /*数据域*/ PNode previous; /*指向前驱*/ PNode next; /*指向后继*/}Node;/*定义链表类型*/typedef struct{ PNode head; /*指向头节点*/ PNode tail; /*指向尾节点*/ int size;}DList;/*分配值为i的节点,并返回节点地址*/Position MakeNode(Item i);/*释放p所指的节点*/void FreeNode(PNode p);/*构造一个空的双向链表*/DList* InitList();/*摧毁一个双向链表*/void DestroyList(DList *plist);/*将一个链表置为空表,释放原链表节点空间*/void ClearList(DList *plist);/*返回头节点地址*/Position GetHead(DList *plist);/*返回尾节点地址*/Position GetTail(DList *plist);/*返回链表大小*/int GetSize(DList *plist);/*返回p的直接后继位置*/Position GetNext(Position p);/*返回p的直接前驱位置*/Position GetPrevious(Position p);/*将pnode所指节点插入第一个节点之前*/PNode InsFirst(DList *plist,PNode pnode);/*将链表第一个节点删除并返回其地址*/PNode DelFirst(DList *plist);/*获得节点的数据项*/Item GetItem(Position p);/*设置节点的数据项*/void SetItem(Position p,Item i);/*删除链表中的尾节点并返回其地址,改变链表的尾指针指向新的尾节点*/PNode Remove(DList *plist);/*在链表中p位置之前插入新节点S*/PNode InsBefore(DList *plist,Position p,PNode s);/*在链表中p位置之后插入新节点s*/PNode InsAfter(DList *plist,Position p,PNode s);/*返回在链表中第i个节点的位置*/PNode LocatePos(DList *plist,int i);/*依次对链表中每个元素调用函数visit()*/void ListTraverse(DList *plist,void (*visit)());#endif
DList.c
#include"DList.h"#include<malloc.h>#include<stdlib.h>/*分配值为i的节点,并返回节点地址*/Position MakeNode(Item i){ PNode p = NULL; p = (PNode)malloc(sizeof(Node)); if(p!=NULL) { p->data = i; p->previous = NULL; p->next = NULL; } return p;}/*释放p所指的节点*/void FreeNode(PNode p){ free(p);}/*构造一个空的双向链表*/DList * InitList(){ DList *plist = (DList *)malloc(sizeof(DList)); PNode head = MakeNode(0); if(plist!=NULL) { if(head!=NULL) { plist->head = head; plist->tail = head; plist->size = 0; } else return NULL; } return plist;}/*摧毁一个双向链表*/void DestroyList(DList *plist){ ClearList(plist); free(GetHead(plist)); free(plist);}/*判断链表是否为空表*/int IsEmpty(DList *plist){ if(GetSize(plist)==0&&GetTail(plist)==GetHead(plist)) return 1; else return 0;}/*将一个链表置为空表,释放原链表节点空间*/void ClearList(DList *plist){ PNode temp,p; p = GetTail(plist); while(!IsEmpty(plist)) { temp = GetPrevious(p); FreeNode(p); p = temp; plist->tail = temp; plist->size--; }}/*返回头节点地址*/Position GetHead(DList *plist){ return plist->head;}/*返回尾节点地址*/Position GetTail(DList *plist){ return plist->tail;}/*返回链表大小*/int GetSize(DList *plist){ return plist->size;}/*返回p的直接后继位置*/Position GetNext(Position p){ return p->next;}/*返回p的直接前驱位置*/Position GetPrevious(Position p){ return p->previous;}/*将pnode所指节点插入第一个节点之前*/PNode InsFirst(DList *plist,PNode pnode){ Position head = GetHead(plist); if(IsEmpty(plist)) plist->tail = pnode; plist->size++; pnode->next = head->next; pnode->previous = head; if(head->next!=NULL) head->next->previous = pnode; head->next = pnode; return pnode; }/*将链表第一个节点删除,返回该节点的地址*/PNode DelFirst(DList *plist){ Position head = GetHead(plist); Position p=head->next; if(p!=NULL) { if(p==GetTail(plist)) plist->tail = p->previous; head->next = p->next; head->next->previous = head; plist->size--; } return p;}/*获得节点的数据项*/Item GetItem(Position p){ return p->data;}/*设置节点的数据项*/void SetItem(Position p,Item i){ p->data = i;}/*删除链表中的尾节点并返回地址,改变链表的尾指针指向新的尾节点*/PNode Remove(DList *plist){ Position p=NULL; if(IsEmpty(plist)) return NULL; else { p = GetTail(plist); p->previous->next = p->next; plist->tail = p->previous; plist->size--; return p; }}/*在链表中p位置之前插入新节点s*/PNode InsBefore(DList *plist,Position p,PNode s){ s->previous = p->previous; s->next = p; p->previous->next = s; p->previous = s; plist->size++; return s;}/*在链表中p位置之后插入新节点s*/PNode InsAfter(DList *plist,Position p,PNode s){ s->next = p->next; s->previous = p; if(p->next != NULL) p->next->previous = s; p->next = s; if(p = GetTail(plist)) plist->tail = s; plist->size++; return s;}/*返回在链表中第i个节点的位置*/PNode LocatePos(DList *plist,int i){ int cnt = 0; Position p = GetHead(plist); if(i>GetSize(plist)||i<1) return NULL; while(++cnt<=i) { p=p->next; } return p;}/*依次对链表中每个元素调用函数visit()*/void ListTraverse(DList *plist,void (*visit)()){ Position p = GetHead(plist); if(IsEmpty(plist)) exit(0); else { while(p->next!=NULL) { p = p->next; visit(p->data); } }}test.c
#include"DList.h"#include<stdio.h>void print(Item i){ printf("数据项为%d \n",i);}main(){ DList *plist = NULL; PNode p = NULL; plist = InitList(); p = InsFirst(plist,MakeNode(1)); InsBefore(plist,p,MakeNode(2)); InsAfter(plist,p,MakeNode(3)); printf("p前驱位置的值为%d\n",GetItem(GetPrevious(p))); printf("p位置的值为%d\n",GetItem(p)); printf("p后继位置的值为%d\n",GetItem(GetNext(p))); printf("遍历输出各节点数据项:\n"); ListTraverse(plist,print); printf("除了头节点该链表共有%d个节点\n",GetSize(plist)); FreeNode(DelFirst(plist)); printf("删除第一个节点后重新遍历输出为:\n"); ListTraverse(plist,print); printf("除了头节点该链表共有%d个节点\n",GetSize(plist)); DestroyList(plist); printf("链表已被销毁\n");}
执行结果如下:
0 0
- Linux c 算法与数据结构--双向链表
- Linux c 算法与数据结构--双向链表
- 数据结构与算法(C语言版)__双向链表
- 数据结构与算法-----双向线性链表
- 算法与数据结构之双向链表
- [数据结构与算法]双向链表
- 数据结构与算法:双向链表
- 数据结构与算法(双向链表)
- java数据结构与算法-双向链表
- 数据结构与算法(C语言描述)——双向链表
- <数据结构与算法>双向循环链表的全面基本框架(C语言描述)
- 数据结构(C#)--双向链表
- 数据结构与算法分析-双向链表的实现
- 算法与数据结构之四----双向链表
- 数据结构与算法Javascript描述(四)双向链表
- 数据结构与算法学习04:双向链表
- 数据结构与算法之双向链表 <二>
- 数据结构与算法Java版——双向链表
- angular模块控制器分离二
- 通达OA 2015界面个性化随笔,不定期更新
- PCA目标函数的推导
- 关于UIApplication单例传值
- Server Tomcat v7.0 Server at localhost failed to start.
- Linux c 算法与数据结构--双向链表
- Java多线程优先级的一些测试
- mysql的权限控制
- Android Studio中常用设置与快捷键
- Mysql group_concat的反向应用实现(Mysql列转行)
- 页面跳转与重定向(之一)
- 网页唤醒app(自定义 URL Scheme 完全指南)
- 按宽度自适应匹配imageview
- HTTP响应头和请求头信息对照表