结构
带头链表里的头结点,实际为"哨兵位",哨兵位结点不存储任何有效元素,只是站在这里"放哨
的"
实现双向链表
List.h
cpp
#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
cpp
#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
cpp
#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;
}