今天写到太晚了,还好明天不上班。
直接上代码:
// 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;
}