看数据结构写代码(7)具有实用意义的双向链表
2015-02-28 17:49
288 查看
今天写到太晚了,还好明天不上班。
直接上代码:
直接上代码:
// LinkList.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <stdlib.h> typedef int ElementType; enum E_STATE { E_STATE_ERROR = 0, E_STATE_OK = 1, }; //具有实用意义的链表,比书里的例子多了一个 前驱指针,因为觉得链表 可以指向 链表的尾部,但不可以 获取前驱,没什么意义 struct LinkNode { ElementType data; LinkNode * next; LinkNode * pre; }; //链表 指向 头指针和 尾指针 struct LinkList { LinkNode * head; LinkNode * tail; int len; }; LinkNode * makeNode(ElementType data){ LinkNode * newNode = (LinkNode *) malloc(sizeof(LinkNode)); if (newNode == NULL) { return NULL;; } //设置新节点 newNode->next = NULL; newNode->pre = NULL; newNode->data = data; return newNode; } E_STATE listInit(LinkList * l){ LinkNode * pHead = (LinkNode *)malloc(sizeof(LinkNode)); if (pHead == NULL) { return E_STATE_ERROR; } pHead->next = NULL; pHead->pre = NULL; l->head = l->tail = pHead; l->len = 0; return E_STATE_OK; } void listClear(LinkList * l){ LinkNode * head = l->head; LinkNode * next = head->next; //在判断是否到了链表的尾部的时候,比 head != l-> tail 方便 while (next != NULL)//后继不为空 { LinkNode * freeNode = next; next = next->next; free(freeNode); } //重置默认参数 l->tail = l->head; l->len = 0; } void listDestory(LinkList *l){ //重置为空表 listClear(l); //释放头指针 free(l->head); l->head = l->tail = NULL; } //插入一个新的尾节点 E_STATE listInsertTail(LinkList * l,ElementType data){ LinkNode * node = makeNode(data); if (node == NULL) { return E_STATE_ERROR; } //设置新的尾节点 node->next = NULL; node->pre = l->tail; l->tail->next = node; l->len++; l->tail = node; return E_STATE_OK; } void listRemoveTail(LinkList * l){ //尾指针的前驱 LinkNode * tailPre = l->tail->pre; //表空时,尾指针 和头指针 是相等的 if (l->head != l->tail)//表不为空 { LinkNode * freeNode = tailPre->next; tailPre->next = NULL; free(freeNode); l->len--; l->tail = tailPre; } } //在 node 节点前插入一个 新节点 E_STATE listInsertBefore(LinkList * l,LinkNode * node,ElementType data){ LinkNode * newNode = makeNode(data); if (newNode == NULL) { return E_STATE_ERROR; } //设置新节点 LinkNode * pre = node->pre; newNode->next = node; newNode->pre = pre; //设置前驱节点 pre->next = newNode; //设置后继节点 node->pre = newNode; l->len ++; return E_STATE_OK; } //在节点后插入 E_STATE listInsertAfter(LinkList * l,LinkNode * node,ElementType data){ LinkNode * newNode = makeNode(data); if (newNode == NULL) { return E_STATE_ERROR; } //设置新节点 LinkNode * nodeNext = node->next; newNode->next = nodeNext; newNode->pre = node; //设置前驱节点 node->next = newNode; //设置后继节点 if (nodeNext != NULL) { nodeNext->pre = newNode; } else//node 为尾指针节点 { l->tail = newNode; } l->len++; return E_STATE_OK; } int listLen(LinkList l){ return l.len; } bool listEmpty(LinkList l){ return l.len == 0 ? true : false; } //第一个节点 LinkNode * listFirstNode(LinkList l){ return l.head->next; } //最后一个节点 LinkNode * listLastNode(LinkList l){ return l.head == l.tail ? NULL : l.tail; } //节点的前驱 LinkNode * listPreNode(LinkList l,LinkNode node){ LinkNode * pre = node.pre; return pre == l.head ? NULL : pre; } LinkNode * listNextNode(LinkList l,LinkNode node){ return node.next; } void listTraverse(LinkList l){ LinkNode * next = l.head->next; printf("----------------正序遍历开始--------------------------\n"); while (next) { printf("----%d-----\n",next->data); next = next->next; } printf("-----------------正序遍历结束-------------------------\n"); } //逆序 void listReverseTraverse(LinkList l){ LinkNode * pre = l.tail; printf("-------------------逆序遍历开始-----------------------\n"); while (pre != l.head) { printf("----%d-----\n",pre->data); pre = pre->pre; } printf("-------------------逆序遍历结束-----------------------\n"); } int _tmain(int argc, _TCHAR* argv[]) { LinkList list; listInit(&list); for (int i = 1; i < 10; i++) { listInsertTail(&list,i); } listRemoveTail(&list); listRemoveTail(&list); LinkNode * pFirstNode = listFirstNode(list); listInsertBefore(&list,pFirstNode,66); LinkNode * pLastNode = listLastNode(list); listInsertAfter(&list,pLastNode,99); listTraverse(list); LinkNode * preNode = listPreNode(list,*pFirstNode); LinkNode * nextNode = listNextNode(list,*pLastNode); printf("%d 前继 : %d, %d 后继 : %d\n",pFirstNode->data,preNode->data,pLastNode->data,nextNode->data); printf("表长:%d\n",listLen(list)); listReverseTraverse(list); return 0; }
相关文章推荐
- 看数据结构写代码(6)双向链表的实现
- 数据结构教程 第九课 循环链表与双向链表
- 数据结构之双向链表的实现
- c语言_数据结构_双向循环链表
- 数据结构基础(12) --双向循环链表的设计与实现
- python——python 数据结构之双向链表的实现
- vxworks源码剖析- 数据结构篇一(双向链表)_1(转)
- 实战数据结构(5)_双向循环链表的基本操作
- 双向链表 - 数据结构
- python 数据结构之双向链表的实现
- 数据结构基础(12) --双向循环链表的设计与实现
- 数据结构之双向链表,头部插入数据
- 数据结构课程设计-----用C#实现双向链表
- 数据结构与算法 2、单向/双向链表
- 数据结构(C实现)------- 双向链表
- bo2-6.cpp 具有实用意义的线性链表(存储结构由c2-5.h定义)的24个基本操作
- 数据结构之静态链表和双向循环链表
- 实战数据结构(5)_双向循环链表的基本操作
- 数据结构基础(12) --双向循环链表的设计与实现
- linux 内核常用数据结构及算法——list(循环双向链表)