一、链表初始化
typedef struct LNode
{
int data;
struct LNode *next;
} LNode, *LinkList;
// 链表初始化
bool ListInit(LinkList &L)
{
L = (LNode *)malloc(sizeof(LNode));
if (L == NULL)
{
perror("malloc LNode fault\n");
return false;
}
L->next = NULL;
return true;
}
二、链表的插入
(1)按位序插入
// 按位序插入,指插入节点为第n个节点
bool ListNodeInsert(LinkList &L, int i, int elem)
{
if (i < 1)
{
perror("insert element falut: i < 1");
return false;
}
LNode *p = FindNode(L, i - 1);
return InsertNode(p, elem);
}
(2)第i个节点之后插入
// 第i个节点之后插入一个新的节点
bool InsertNextNode(LinkList &L, int i, int elem)
{
if (i < 1)
{
perror("insert element falut: i < 1");
return false;
}
LNode *p = FindNode(L, i);
return InsertNode(p, elem);
}
(3)指定节点前面插入
// 在指定节点前面插入一个节点
bool InsertFrontNode(LinkList &L, int i, int elem)
{
if (i < 1)
{
perror("insert element falut: i < 1");
return false;
}
LNode *p = FindNode(L, i);
if (p == NULL)
{
perror("insert i Illegal");
return false;
}
LNode *s = (LNode *)malloc(sizeof(LNode));
if (s == NULL)
{
perror("Malloc LNode fault");
return false;
}
s->next = p->next;
s->data = p->data;
p->next = s;
p->data = elem;
return true;
}
(4)插入节点详细描述
// 插入节点详细步骤
bool InsertNode(LNode *p, int elem)
{
if (p == NULL)
{
perror("insert i Illegal");
return false;
}
LNode *s = (LNode *)malloc(sizeof(LNode));
if (s == NULL)
{
perror("Malloc LNode fault");
return false;
}
s->data = elem;
s->next = p->next;
p->next = s;
return true;
}
三、查找
(1)按位序查找
// 按位序查找
bool GetElem(LinkList &L, int i, int &elem)
{
if (i < 1)
{
perror("GetElem falut: i < 1");
return false;
}
LNode *p = FindNode(L, i);
if (p == NULL)
{
perror("Getelem's Node i Illegal");
return false;
}
elem = p->data;
return true;
}
(2)按值查找
// 按值查找
LNode *FindElem(LinkList &L, int elem)
{
LNode *p = L->next;
while (p != NULL && p->data != elem)
{
p = p->next;
}
return p;
}
(3)查找指定节点
// 查找指定节点
LNode *FindNode(LinkList &L, int i)
{
int k = 0;
LNode *p = L;
while (p != NULL && k < i)
{
p = p->next;
k++;
}
return p;
}
四、删除节点
(1)按位序删除节点
// 按位序删除节点
bool DeleteNode(LinkList &L, int i, int &elem)
{
if (i < 1)
{
perror("insert element falut: i < 1");
return false;
}
LNode *p = FindNode(L, i - 1);
if (p == NULL || p->next == NULL)
{
perror("delete i Illegal");
return false;
}
LNode *q = p->next;
elem = q->data;
p->next = q->next;
free(q);
return false;
}
(2)删除指定节点
// 删除指定节点
bool DeletePointNode(LinkList &L, int i, int &elem)
{
if (i < 1)
{
perror("insert element falut: i < 1");
return false;
}
LNode *p = FindNode(L, i);
if (p == NULL)
{
perror("delete i Illegal");
return false;
}
elem = p->data; // 获取指定节点的数据
LNode *q = p->next; // 找到指定节点的后继节点
p->data = q->data; // 将后继节点的数据复制到指定节点p
p->next = q->next; // 让指定节点p的next指向原本后继节点的下一个节点
// 这里就相当于把指定节点的后继节点给覆盖到指定节点
free(q);
return true;
}
五、计算链表长度及输出
(1)计算
// 计算链表长度
void ClacListlength(LinkList L)
{
int length = 0;
LNode *p = L;
while(p->next)
{
length++;
p = p->next;
}
printf("List length is %d\n",length);
}
(2)输出
// 输出链表
void ListPrint(LinkList L)
{
LNode *p = L->next;
while (p != NULL)
{
printf("%d\n", p->data);
p = p->next;
}
}
六、整体代码演示
/*
此链表的操作基于带头节点的操作
不带头节点的操作,在插入第一个节点操作需做特殊处理
不带头节点除第一个节点外其它操作与带头节点一致
需注意的是当前p指向的是第一个节点
*/
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
typedef struct LNode
{
int data;
struct LNode *next;
} LNode, *LinkList;
// 链表初始化
bool ListInit(LinkList &L)
{
L = (LNode *)malloc(sizeof(LNode));
if (L == NULL)
{
perror("malloc LNode fault\n");
return false;
}
L->next = NULL;
return true;
}
// 插入节点详细步骤
bool InsertNode(LNode *p, int elem)
{
if (p == NULL)
{
perror("insert i Illegal");
return false;
}
LNode *s = (LNode *)malloc(sizeof(LNode));
if (s == NULL)
{
perror("Malloc LNode fault");
return false;
}
s->data = elem;
s->next = p->next;
p->next = s;
return true;
}
// 查找指定节点
LNode *FindNode(LinkList &L, int i)
{
int k = 0;
LNode *p = L;
while (p != NULL && k < i)
{
p = p->next;
k++;
}
return p;
}
// 按位序插入,指插入节点为第n个节点
bool ListNodeInsert(LinkList &L, int i, int elem)
{
if (i < 1)
{
perror("insert element falut: i < 1");
return false;
}
LNode *p = FindNode(L, i - 1);
return InsertNode(p, elem);
}
// 第i个节点之后插入一个新的节点
bool InsertNextNode(LinkList &L, int i, int elem)
{
if (i < 1)
{
perror("insert element falut: i < 1");
return false;
}
LNode *p = FindNode(L, i);
return InsertNode(p, elem);
}
// 在指定节点前面插入一个节点
bool InsertFrontNode(LinkList &L, int i, int elem)
{
if (i < 1)
{
perror("insert element falut: i < 1");
return false;
}
LNode *p = FindNode(L, i);
if (p == NULL)
{
perror("insert i Illegal");
return false;
}
LNode *s = (LNode *)malloc(sizeof(LNode));
if (s == NULL)
{
perror("Malloc LNode fault");
return false;
}
s->next = p->next;
s->data = p->data;
p->next = s;
p->data = elem;
return true;
}
// 按位序删除节点
bool DeleteNode(LinkList &L, int i, int &elem)
{
if (i < 1)
{
perror("insert element falut: i < 1");
return false;
}
LNode *p = FindNode(L, i - 1);
if (p == NULL || p->next == NULL)
{
perror("delete i Illegal");
return false;
}
LNode *q = p->next;
elem = q->data;
p->next = q->next;
free(q);
return false;
}
// 删除指定节点
bool DeletePointNode(LinkList &L, int i, int &elem)
{
if (i < 1)
{
perror("insert element falut: i < 1");
return false;
}
LNode *p = FindNode(L, i);
if (p == NULL)
{
perror("delete i Illegal");
return false;
}
elem = p->data; // 获取指定节点的数据
LNode *q = p->next; // 找到指定节点的后继节点
p->data = q->data; // 将后继节点的数据复制到指定节点p
p->next = q->next; // 让指定节点p的next指向原本后继节点的下一个节点
// 这里就相当于把指定节点的后继节点给覆盖到指定节点
free(q);
return true;
}
// 按位序查找
bool GetElem(LinkList &L, int i, int &elem)
{
if (i < 1)
{
perror("GetElem falut: i < 1");
return false;
}
LNode *p = FindNode(L, i);
if (p == NULL)
{
perror("Getelem's Node i Illegal");
return false;
}
elem = p->data;
return true;
}
// 按值查找
LNode *FindElem(LinkList &L, int elem)
{
LNode *p = L->next;
while (p != NULL && p->data != elem)
{
p = p->next;
}
return p;
}
// 计算链表长度
void ClacListlength(LinkList L)
{
int length = 0;
LNode *p = L;
while(p->next)
{
length++;
p = p->next;
}
printf("List length is %d\n",length);
}
// 输出链表
void ListPrint(LinkList L)
{
LNode *p = L->next;
while (p != NULL)
{
printf("%d\n", p->data);
p = p->next;
}
}
int main()
{
LinkList L;
ListInit(L);
for (int i = 1; i <= 10; i++)
{
ListNodeInsert(L, i, i);
}
// 指定节点之后插入一个新的节点
InsertNextNode(L, 2, 6);
// 指定节点之前插入一个新的节点
InsertFrontNode(L, 4, 5);
ListPrint(L);
// 删除指定节点并返回指定节点的数据
int elem = 0;
DeleteNode(L, 4, elem);
printf("Deleted data is %d Node\n", elem);
ListPrint(L);
// 删除指定节点(方法二)并返回指定节点的数据
DeletePointNode(L, 2, elem);
printf("Deleted data is %d Node\n", elem);
ListPrint(L);
// 获取节点数据
GetElem(L, 2, elem);
printf("No.2 Node's data is %d\n", elem);
// 查找链表中是否存在数据elem
if (FindElem(L, 8))
{
printf("exist Node\n");
}
else
{
printf("Can't find eNode\n");
}
ClacListlength(L);
return 0;
}