您的位置:首页 > 理论基础 > 数据结构算法

看数据结构写代码(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;
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息