结构
带头链表里的头结点,实际为“哨兵位”,哨兵位结点不存储任何有效元素,只是站在这里“放哨
的”
实现双向链表
List.h
#pragma once#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>//定义双向链表结点的结构
typedef int LTDataType;
typedef struct ListNode
{int data;struct ListNode* next;struct ListNode* prev;}LTNode;//初始化
//void LTInit(LTNode** pphead);
LTNode* LTInit();void LTPrint(LTNode* phead);//插入
//1.传一级还是二级,要看pphead指向的结点会不会发生改变
//2.如果发生改变,那么pphead的改变要影响实参,传二级
//3.如果不发生改变,pphead不会影响实参,传一级
void LTPushBack(LTNode* phead, LTDataType x);
void LTPushFront(LTNode* phead, LTDataType x);//删除
void LTPopBack(LTNode* phead);
void LTPopFront(LTNode* phead);bool LTEmpty(LTNode* phead);//查找
LTNode* LTFind(LTNode* phead, LTDataType x);//在pos位置之后插入结点
void LTInsert(LTNode* pos, LTDataType x);
//删除指定位置的结点
void LTErase(LTNode* pos);
//销毁
void LTDesTroy(LTNode** pphead);//为了保持接口的一致性,优化接口都为一级指针
void LTDesTroy2(LTNode* phead);
List.c
#include"List.h"
LTNode* LTBuyNode(LTDataType x)
{LTNode* newnode = (LTNode*)malloc(sizeof(LTNode));if (newnode == NULL){perror("malloc fail");exit(1);}newnode->data = x;newnode->next = newnode->prev = newnode;
}
//初始化
//void LTInit(LTNode** pphead)
//{
// //创建一个头结点(哨兵位)
// *pphead = LTBuyNode(-1);
//
//}LTNode* LTInit()
{LTNode* phead = LTBuyNode(-1);return phead;
}void LTPushBack(LTNode* phead, LTDataType x)
{assert(phead);LTNode* newnode = LTBuyNode(x);newnode->next = phead;newnode->prev = phead->prev;phead->prev->next = newnode;phead->prev = newnode;
}void LTPushFront(LTNode* phead, LTDataType x)
{assert(phead);LTNode* newnode = LTBuyNode(x);newnode->next = phead->next;newnode->prev = phead;phead->next->prev = newnode;phead->next = newnode;
}void LTPrint(LTNode* phead)
{LTNode* pcur = phead->next;while (pcur!=phead){printf("%d->", pcur->data);pcur = pcur->next;}printf("\n");
}bool LTEmpty(LTNode* phead)
{assert(phead);return phead->next == phead;
}void LTPopBack(LTNode* phead)
{assert(phead);assert(!LTEmpty(phead));LTNode* del = phead->prev;LTNode* prev = del->prev;prev->next = phead;phead->prev = prev;free(del);del = NULL;
}void LTPopFront(LTNode* phead)
{assert(phead);assert(!LTEmpty(phead));LTNode* del = phead->next;del->next->prev = phead;phead->next = del->next; free(del);del = NULL;}LTNode* LTFind(LTNode* phead, LTDataType x)
{assert(phead);LTNode* pcur = phead->next;while(pcur != phead){if (pcur->data == x){return pcur;}pcur = pcur->next;}return NULL;
}void LTInsert(LTNode* pos, LTDataType x)
{assert(pos);LTNode* newnode = LTBuyNode(x);newnode->next = pos->next;newnode->prev = pos;pos->next->prev = newnode;pos->next = newnode;
}void LTErase(LTNode* pos)
{assert(pos);pos->prev->next = pos->next;pos->next->prev = pos->prev;free(pos);pos = NULL;
}void LTDesTroy(LTNode** pphead)
{assert(pphead && *pphead);LTNode* pcur = (*pphead)->next;while (pcur!=*pphead){LTNode* Next = pcur->next;free(pcur);pcur = Next; }//销毁哨兵位结点free(*pphead);*pphead = NULL;pcur = NULL;
}void LTDesTroy2(LTNode* phead)
{assert(phead);LTNode* pcur = phead->next;while (pcur != phead){LTNode* Next = pcur->next;free(pcur);pcur = Next;}free(phead);phead = pcur = NULL;
}
test.c
#include"List.h"void ListTest01()
{//创建双向链表/*LTNode* plist = NULL;LTInit(&plist);*/LTNode*plist=LTInit();LTPushBack(plist, 1);LTPushBack(plist, 2);LTPushBack(plist, 3);LTPushBack(plist, 4);LTPrint(plist);/*LTPushFront(plist, 1);LTPrint(plist);LTPushFront(plist, 2);LTPrint(plist);LTPushFront(plist, 3);LTPrint(plist);LTPushFront(plist, 4);LTPrint(plist);*//*LTPopBack(plist);LTPrint(plist);LTPopBack(plist);LTPrint(plist);LTPopBack(plist);LTPrint(plist);LTPopBack(plist);LTPrint(plist);*//*LTPopFront(plist);LTPrint(plist);LTPopFront(plist);LTPrint(plist);LTPopFront(plist);LTPrint(plist);LTPopFront(plist);LTPrint(plist);*///LTNode* pos = LTFind(plist, 2);/*if (pos == NULL){printf("没有找到!\n");}else{printf("找到了!\n");}*//*LTInsert(pos, 13);LTPrint(plist);*//*LTErase(pos);LTPrint(plist);*///LTDesTroy(&plist);LTDesTroy2(plist);
}int main()
{ListTest01();return 0;
}