Fork me on GitHub

链表基本操作

学习链表有段时间了,今天给大家整理了有关链表的基本操作,例如链表的创建、增、删、查等基本操作

结构体定义

1
2
3
4
5
6
7
typedef int DataType;

typedef struct ListNode
{
DataType data;
struct ListNode *next;
} ListNode;

头文件的定义

其中包含了面试题的头文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
void ListInit(ListNode **Node);

void ListDestroy(ListNode **Node);

void ListPushFront(ListNode **Node,DataType data);

void ListPushBack(ListNode **Node,DataType data);

void ListPopFront(ListNode **Node);

void LIstPopBack(ListNode **Node);

ListNode* ListFind(ListNode *Node , DataType data);

void ListInsert(ListNode **Node,ListNode *pos,DataType data);

void ListDelete(ListNode **Node,ListNode *pos);

// 删除一个无头单链表的非尾结点(不能遍历链表)
void ListDelNotFirst(ListNode **Node ,ListNode *pos);

//递归写法
void ListReversePrint(ListNode *Node);

void ListReveresePrint2(ListNode *Node);

void ListPrint(ListNode *Node);

void ListIntersection(ListNode *list1,ListNode *list2);
void TestListInterstion();

ListNode* ListJosephCircle(ListNode *list,DataType k);
void TestListJosephCircle();

ListNode *ListMerge(ListNode *list1,ListNode *list2);
void TestMerge();

void ListFindMidNode(ListNode *list);
void TestFindMid();

void ListFindTailK(ListNode *list,DataType k);
void TestFindTailK();

void ListDelTailK(ListNode *list, DataType k);
void TestDelTailK();

链表的具体基本操作 文件名(List.c)

链表的初始化及销毁

1
2
3
4
5
6
7
8
9
10
11
#include "List.h"
void ListInit(ListNode **Node)
{
assert(Node != NULL);
*Node = NULL;
}

void ListDestroy(ListNode **Node)
{
*Node = NULL;
}

链表结点的创建

1
2
3
4
5
6
7
8
9
static ListNode * CreateNode(DataType data)
{
ListNode *newNode = (ListNode *)malloc(sizeof(ListNode));
assert(newNode);
newNode->data = data;
newNode->next = NULL;

return newNode;
}

头插法

1
2
3
4
5
6
7
8
9
10
11
//头插
void ListPushFront(ListNode **Node,DataType data)
{
//assert(Node != NULL);

ListNode *newNode = CreateNode(data); // *newNode 用来存储新结点的地址
newNode->next = *Node; // 把头结点的地址赋给新结点

*Node = newNode; // 把新结点的地址赋给头结点 ( *Node用来存储下一个结点的地址)

}

尾插法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//尾插
void ListPushBack(ListNode **Node,DataType data)
{
ListNode *newNode = CreateNode(data);

ListNode *cur = *Node; //把头结点地址赋给cur

if (*Node == NULL) //判断头结点是否为空,如果为空,将新的结点赋给头结点(如果是空链表)
{
*Node = newNode;
return;
}

while (cur->next !=NULL) //如果头结点不为空,则将判断头结点指向下一个结点以及后面的结点是否为空
{ // 如果有空结点,则将赋给当前cur,
cur = cur->next;
}
cur->next = newNode; //将新的结点地址赋给当前的下一结点
}

头结点的删除

1
2
3
4
5
6
7
8
9
10
void ListPopFront(ListNode **Node)
{
//assert(Node != NULL);
//assert(*Node != NULL);

ListNode *del = *Node; // 将头结点的地址del,然后指向下一个结点并赋给Node,然后释放del(头结点存储在del中)

*Node = del->next;
free(del);
}

尾结点的删除

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
void ListPopBack(ListNode **Node)
{
/*ListNode *del = *Node ;
while (del->next != NULL)
{
del = del->next;
}
*Node = del->next;

free(del);*/


ListNode *del;
ListNode *cur = *Node;

while (cur->next->next != NULL) // cur->next->next :头指针指向头结点,然后指向下一个结点
{ // 判断并找到最后一个结点的地址,赋给del
cur = cur->next;
}

del = cur->next;
cur->next = NULL;
free(del);
}

查找

1
2
3
4
5
6
7
8
9
10
11
12
13
//查找
ListNode* ListFind(ListNode *Node , DataType data)
{
ListNode *cur;
for (cur = Node;cur != NULL;cur=cur->next)
{
if (data == cur->data)
{
return cur;
}
}
return NULL;
}

结点前插入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//在某结点前插入结点
void ListInsert(ListNode **Node,ListNode *pos,DataType data)
{
ListNode *cur = *Node;
ListNode *newNode;
if (*Node == pos)
{
ListPopFront(Node);
return;
}


while (cur->next != pos)
{
cur = cur->next;
}

newNode = CreateNode(data);
newNode->next = cur->next;
cur->next =newNode;

}

删除指定结点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//删除指定结点
void ListDelete(ListNode **Node,ListNode *pos)
{
ListNode *cur = *Node;
if (*Node == pos)
{
ListPopFront(Node);
}
while (cur->next != pos)
{
cur = cur->next;
}

cur->next = pos->next;
free(pos);
}

单链表的打印

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//单链表的打印
void ListPrint(ListNode *Node)
{
ListNode *cur = Node;
if (Node == NULL)
{
return;
}

while (cur != NULL)
{
printf("%d--> ",cur->data);
cur = cur->next;
}
}

本文标题:链表基本操作

文章作者:LiuXiaoKun

发布时间:2018年10月05日 - 12:10

最后更新:2018年10月05日 - 13:10

原始链接:https://LiuZiQiao.github.io/2018/10/05/链表基本操作/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

0%