实现双向循环链表的创建新节点,初始化,销毁,增加,删除,查找,求长度以及判空等基本操作。
头文件 List.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int LTDataType;
//双向循环带头链表
typedef struct ListNode
{
struct ListNode* _next; //后继
struct ListNode* _prev; //前驱
LTDataType _data; //数据域
}ListNode;
typedef struct List
{
struct ListNode* _head;
struct ListNode* _tail;
int _size;
}List;
void ListInit(List* lt);
void ListDestory(List* lt);
void ListPushBack(List* lt, LTDataType x);
void ListPushFront(List* lt, LTDataType x);
void ListPopBack(List* lt,ListNode* pos,LTDataType x);
void ListPopFront(List* lt, ListNode* pos, LTDataType x);
ListNode* BuyListNode(LTDataType x);
ListNode* ListFind(List* lt, LTDataType x);
void ListInsert(ListNode* pos, LTDataType x);
void ListErase(List* lt,ListNode* pos,LTDataType x);
int ListSize(List* lt);
int ListEmpty(List* lt);
void ListPrint(List* lt);
void testListNode();
test.c
1.创建新节点
#include "List.h"
ListNode* BuyListNode(LTDataType x)
{
ListNode* newnode = (ListNode*)malloc(sizeof(ListNode));
if (newnode != NULL)
{
newnode->_data = x;
newnode ->_prev = NULL;
newnode->_next = NULL;
}
return newnode;
}
2.链表初始化
void ListInit(List* lt)
{
assert(lt != NULL);
lt->_head= BuyListNode(0);
lt->_head->_next = lt->_head;
lt->_head->_prev = lt->_head;
}
3.链表销毁
void ListDestory(List* lt)
{
ListNode* cur = NULL;
ListNode* tail=NULL;
assert(lt!= NULL);
cur = lt;
while (cur!=tail)
{
ListNode* del = cur;
cur = cur->_next;
free(del);
del = NULL;
}
free(cur);
}
4.在链表中插入数据 注:因为是双向循环链表在任何地方插入都是一样的实现。
void ListInsert(ListNode* pos, LTDataType x) //pos之前插入 prev newnode pos
{
assert(pos != NULL);
ListNode* newnode;
newnode = BuyListNode(3);
newnode->_data = x;
ListNode* prev = pos->_prev;
prev->_next = newnode;
newnode->_prev = prev;
newnode->_next = pos;
pos->_prev = newnode;
}
void ListPushBack(List* lt, LTDataType x)// tail newnode head
{
ListInsert(lt->_head, x);
}
void ListPushFront(List* lt, LTDataType x) // tail newnode head
{
ListInsert(lt->_head, x);
}
5.查找链表中指定位置元素
ListNode* ListFind(List* lt, LTDataType x)
{
int i = 0;
while (lt != NULL && lt->_head->_data != x)//寻找值为x的元素**注意这里循环的条件不能写反。原因,当L == NULL 时候 L->data会出错
{
i++;
lt = lt->_head->_next;
}
if (lt == NULL) //如果没找到返回-1
return -1;
else
return x;
}
6.删除指定位置元素
void ListErase(List* lt,ListNode* pos,LTDataType x)
{
if (lt == NULL && pos < 1)
{
return;
}
if (pos>ListSize(lt))
{
return;
}
ListNode *pNode = lt;
int count = 0;
while (count < ListSize(lt))
{
pNode = pNode->_next;
count++;
}
if (count != pos)
return;
x = pNode->_data;
pNode->_prev->_next = pNode->_next;
pNode->_next->_prev = pNode->_prev;
free(pNode);
pNode = NULL;
}
void ListPopBack(List* lt, ListNode* pos, LTDataType x) // tail head
{
assert(lt != NULL);
ListErase(lt->_head, pos, x);
}
void ListPopFront(List* lt, ListNode* pos, LTDataType x)
{
assert(lt != NULL);
ListErase(lt->_head, pos, x);
}
7.求链表长度
int ListSize(List* lt)
{
int size = 0;
assert(lt != NULL);
if (lt->_head!=lt->_head->_prev)
{
++size;
lt->_head = lt->_head->_next;
}
return size;
}
9.判断链表是否为空
int ListEmpty(List* lt)
{
if (ListSize(lt) == 0 && lt->_head->_next == lt->_head->_prev)
return 1;
else
return 0;
}
10.打印链表
void ListPrint(List* lt)
{
ListNode* cur = lt->_head->_next;
while (cur != lt->_head)
{
printf("%d ", cur->_data);
cur = cur->_next;
}
printf("\n");
}
主函数
void testListNode()
{
ListNode* s;
ListInit(&s);
ListPushBack(&s, 1);
ListPushBack(&s, 2);
ListPushBack(&s, 3);
ListPushBack(&s, 4);
ListPrint(&s);
int ret = ListFind(&s, 3);
if (ret != -1)
{
printf("%d ", ret);
}
else
{
printf("找不到");
}
printf("\n");
int size=ListSize(&s);
printf("%d ", size);
printf("\n");
int n = ListEmpty(&s);
printf("%d ", n);
}
int main()
{
testListNode();
system("pause");
return;
}