1、双向链表示意图
2、双向链表实现
(1)结构体定义
typedef int LTDataType;
typedef struct ListNode
{
LTDataType data;
struct ListNode* prev;
struct ListNode* next;
}LTNode;
(2)初始化
/****************初始化*****************/
LTNode* ListInit(LTNode* phead)
{
//哨兵位头结点
phead = (LTNode*)malloc(sizeof(LTNode));
phead->next = phead;
phead->prev = phead;
return phead;
}
(3)打印数据
/****************打印*****************/
void ListPrint(LTNode* phead)
{
assert(phead);
LTNode* cur = phead->next;//跳过头结点,头结点无数据
while(cur != phead)
{
printf("%d ",cur->data);
cur = cur->next;
}
printf("\n");
}
(4)开辟内存
/****************开辟内存*****************/
LTNode* ListCreat(LTDataType x)
{
LTNode* newnode = (LTNode*)malloc(sizeof(LTNode));
newnode->data = x;
newnode->next = NULL;
newnode->prev = NULL;
return newnode;
}
(5)销毁内存
/****************销毁内存*****************/
void ListDestroy(LTNode* phead)
{
assert(phead);
LTNode* cur = phead->next;
while(cur != phead)
{
LTNode* next = cur->next;
free(cur);
cur = next;
}
free(phead);
}
(6)尾插
/*****************尾插*****************/
void ListPushBack(LTNode* phead,LTDataType x)
{
assert(phead);
LTNode* newnode = ListCreat(x);
//phead->prev尾,找尾
LTNode* tail = phead->prev;
//链接
tail->next = newnode;
newnode->prev = tail;
newnode->next = phead;
phead->prev = newnode;
//第二种方法:ListInsertBefore(phead,x);
}
(7)尾删
/*****************尾删*****************/
void ListPopBack(LTNode* phead)
{
assert(phead);
assert(phead->next != phead);//链表为空不能删除,保留头结点
//找尾
LTNode* tail = phead->prev;
tail->prev->next = phead;
phead->prev = tail->prev;
free(tail);
//第二种方法;ListErase(phead->prev);
}
(8)头插
/*****************头插*****************/
void ListPushFront(LTNode* phead,LTDataType x)
{
assert(phead);
LTNode* newnode = ListCreat(x);
//phead->next头,找头
LTNode* head = phead->next;
//链接
phead->next = newnode;
newnode->prev = phead;
newnode->next = head;
head->prev = newnode;
//第二种方法;ListInsertBefore(phead->next,x);
}
(9)头删
/*****************头删*****************/
void ListPopFront(LTNode* phead)
{
assert(phead);
assert(phead->next != phead);//链表为空不能删除,保留头结点
//找头
LTNode* head = phead->next;
phead->next = head->next;
head->next->prev = phead;
free(head);
//第二种方法;ListErase(phead->next);
}
(10)查找
/*****************查找 *****************/
LTNode* ListFind(LTNode* phead,LTDataType x)
{
assert(phead);
LTNode* cur = phead->next;
while(cur!= phead)
{
if(cur->data == x)
{
return cur;
}
cur = cur->next;
}
return NULL;//没有找到
}
(11)指定位置插入
/*****************指定位置之前插入*****************/
void ListInsertBefore(LTNode* pos,LTDataType x)
{
assert(pos);
LTNode* newnode = ListCreat(x);
LTNode* last = pos->prev;//保存前一个
last->next = newnode;
newnode->prev = last;
newnode->next = pos;
pos->prev = newnode;
}
/*****************指定位置之后插入 *****************/
void ListInsertAfter(LTNode* pos,LTDataType x)
{
assert(pos);
LTNode* newnode = ListCreat(x);
LTNode* Next = pos->next;//保存后一个
pos->next = newnode;
newnode->prev = pos;
newnode->next = Next;
Next->prev = newnode;
}
(12)指定位置删除
/*****************指定位置删除*****************/
void ListErase(LTNode* pos)
{
assert(pos);
LTNode* Last = pos->prev;//保存前一个
LTNode* Next = pos->next;//保存后一个
Last->next = Next;
Next->prev = Last;
free(pos);
}
3、函数
(1)main.c
#include <stdio.h>
#include <stdlib.h>
#include "List.h"
void ListTest1()
{
LTNode* plist = ListInit(plist);
//尾插
ListPushBack(plist,1);
ListPushBack(plist,2);
ListPushBack(plist,3);
ListPushBack(plist,4);
ListPrint(plist);
//尾删
ListPopBack(plist);
ListPopBack(plist);
ListPopBack(plist);
ListPopBack(plist);
ListPrint(plist);
//头插
ListPushFront(plist,1);
ListPushFront(plist,2);
ListPushFront(plist,3);
ListPushFront(plist,4);
ListPrint(plist);
//头删
ListPopFront(plist);
ListPopFront(plist);
ListPopFront(plist);
ListPopFront(plist);
ListPrint(plist);
//销毁链表
ListDestroy(plist);
plist = NULL;
}
void ListTest2()
{
LTNode* plist = ListInit(plist);
//尾插
ListPushBack(plist,1);
ListPushBack(plist,2);
ListPushBack(plist,3);
ListPushBack(plist,4);
ListPushBack(plist,3);
ListPushBack(plist,2);
ListPrint(plist);
//找到并删除
LTNode* pos = ListFind(plist,3);
while(pos != NULL)
{
ListErase(pos);
pos = ListFind(plist,3);
}
ListPrint(plist);
//找到并改变
LTNode* pos1 = ListFind(plist,2);
while(pos1 != NULL)
{
pos1->data = 7;
pos1 = ListFind(plist,2);
}
ListPrint(plist);
ListDestroy(plist);
plist = NULL;
}
int main(int argc, char *argv[])
{
//ListTest1();
ListTest2();
return 0;
}
(2)List.c
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "List.h"
/****************初始化*****************/
LTNode* ListInit(LTNode* phead)
{
//哨兵位头结点
phead = (LTNode*)malloc(sizeof(LTNode));
phead->next = phead;
phead->prev = phead;
return phead;
}
/****************打印*****************/
void ListPrint(LTNode* phead)
{
assert(phead);
LTNode* cur = phead->next;//跳过头结点,头结点无数据
while(cur != phead)
{
printf("%d ",cur->data);
cur = cur->next;
}
printf("\n");
}
/****************开辟内存*****************/
LTNode* ListCreat(LTDataType x)
{
LTNode* newnode = (LTNode*)malloc(sizeof(LTNode));
newnode->data = x;
newnode->next = NULL;
newnode->prev = NULL;
return newnode;
}
/****************销毁内存*****************/
void ListDestroy(LTNode* phead)
{
assert(phead);
LTNode* cur = phead->next;
while(cur != phead)
{
LTNode* next = cur->next;
free(cur);
cur = next;
}
free(phead);
}
/*****************尾插*****************/
void ListPushBack(LTNode* phead,LTDataType x)
{
assert(phead);
LTNode* newnode = ListCreat(x);
//phead->prev尾,找尾
LTNode* tail = phead->prev;
//链接
tail->next = newnode;
newnode->prev = tail;
newnode->next = phead;
phead->prev = newnode;
//第二种方法:ListInsertBefore(phead,x);
}
/*****************头插*****************/
void ListPushFront(LTNode* phead,LTDataType x)
{
assert(phead);
LTNode* newnode = ListCreat(x);
//phead->next头,找头
LTNode* head = phead->next;
//链接
phead->next = newnode;
newnode->prev = phead;
newnode->next = head;
head->prev = newnode;
//第二种方法;ListInsertBefore(phead->next,x);
}
/*****************尾删*****************/
void ListPopBack(LTNode* phead)
{
assert(phead);
assert(phead->next != phead);//链表为空不能删除,保留头结点
//找尾
LTNode* tail = phead->prev;
tail->prev->next = phead;
phead->prev = tail->prev;
free(tail);
//第二种方法;ListErase(phead->prev);
}
/*****************头删*****************/
void ListPopFront(LTNode* phead)
{
assert(phead);
assert(phead->next != phead);//链表为空不能删除,保留头结点
//找头
LTNode* head = phead->next;
phead->next = head->next;
head->next->prev = phead;
free(head);
//第二种方法;ListErase(phead->next);
}
/*****************查找 *****************/
LTNode* ListFind(LTNode* phead,LTDataType x)
{
assert(phead);
LTNode* cur = phead->next;
while(cur!= phead)
{
if(cur->data == x)
{
return cur;
}
cur = cur->next;
}
return NULL;//没有找到
}
/*****************指定位置之前插入*****************/
void ListInsertBefore(LTNode* pos,LTDataType x)
{
assert(pos);
LTNode* newnode = ListCreat(x);
LTNode* last = pos->prev;//保存前一个
last->next = newnode;
newnode->prev = last;
newnode->next = pos;
pos->prev = newnode;
}
/*****************指定位置之后插入 *****************/
void ListInsertAfter(LTNode* pos,LTDataType x)
{
assert(pos);
LTNode* newnode = ListCreat(x);
LTNode* Next = pos->next;//保存后一个
pos->next = newnode;
newnode->prev = pos;
newnode->next = Next;
Next->prev = newnode;
}
/*****************指定位置删除*****************/
void ListErase(LTNode* pos)
{
assert(pos);
LTNode* Last = pos->prev;//保存前一个
LTNode* Next = pos->next;//保存后一个
Last->next = Next;
Next->prev = Last;
free(pos);
}
(3)List.h
typedef int LTDataType;
typedef struct ListNode
{
LTDataType data;
struct ListNode* prev;
struct ListNode* next;
}LTNode;
LTNode* ListInit(LTNode* phead);//初始化
void ListPrint(LTNode* phead);//打印
LTNode* ListCreat(LTDataType x);//开辟内存
void ListDestroy(LTNode* phead);//销毁内存
void ListPushBack(LTNode* phead,LTDataType x);//尾插
void ListPopBack(LTNode* phead);//尾删
void ListPushFront(LTNode* phead,LTDataType x);//头插
void ListPopFront(LTNode* phead);//头删
LTNode* ListFind(LTNode* phead,LTDataType x);//查找
void ListErase(LTNode* pos);//指定位置删除
void ListInsertBefore(LTNode* pos,LTDataType x);//指定位置之前插入
void ListInsertAfter(LTNode* pos,LTDataType x);//指定位置之后插入
标签:实现,next,链表,LTNode,phead,双向,newnode,prev,plist
From: https://blog.csdn.net/qq_63057731/article/details/140871874