单链表
一、单链表的构成
链表:由一个个结点构成,每个结点一般采用结构体的形式组织,一个结点分为数据域和指针域
数据域:存放各种实际的数据,如num,score等
指针域:存放下一个结点的首地址,如next等
typedef struct student
{
int num;
char name[20];
struct student*next;
}STU;
头结点
数据域:可以不存储任何信息
指针域:指向首结点
二、单链表的数据结构
1.预编译部分
#include<stdio.h>
#include<stdlib.h>
2.宏定义部分(bool函数)
#define bool char
#define true 1
#define false 0
3.自定义数据元素类型
typedef int ElemType;
4.单链表的结构体
typedef struct Node
{
ElemType data;
struct LNode* next;
}LNode,*LinkList;//头指针指向头结点,头结点指向链表
//LNode为普通结点的类型,*LinkList为头指针的指针类型
5.单链表的初始化(头结点的初始化)
bool InitLinkList(LinkList L)
{
//L=(LNode*)malloc(sizeof(LNode));不能放在这
L->data=0;//头结点的data域用来存储表长
L->next=NULL;//头结点的next域用来指向链表的第一个结点
}
int main()
{
LinkList L;//L是一个指针,还没有赋值实体化
L=(LNode*)malloc(sizeof(LNode));//放在这,若放在上面L指向NULL,没有指向它之前开辟的空间
InitLinkList(L);
printf("%d",L->data);
return 0;
}
6.单链表的打印
bool PrintLinkList(LinkList L)
{
LNode *p;
p=L;
while(p->next)
{
p=p->next;
printf("%d->",p->data);
}
printf("NULL\n");
return true;
}
7.单链表的头插法
bool HeadInsertLinkList(LinkList L)
{
LNode *NewNode;//新结点
ElemType NewNode_data;//新结点的数据域值
printf("Please enter anumber(9999 means the end):");
scanf("%d",&NewNode_data);
while(NewNode_data!=9999)
{
//进行插入操作
NewNode=(LNode*)malloc(sizeof(LNode));
NewNode->next=L->next;
L->next=NewNode;
NewNode->data=NewNode_data;
L->data++;
printf("Please enter anumber(9999 means the end):");
scanf("%d",&NewNode_data);
}
return true;
}
int main()
{
LinkList L;//L是一个指针,还没有赋值实体化
L=(LNode*)malloc(sizeof(LNode));//放在这,若放在上面L指向NULL,没有指向它之前开辟的空间
InitLinkList(L);
HeadInsertLinkList(L);
PrintLinkList(L);
return 0;
}
8.单链表的尾插法
bool TailInsertLinkList(LinkList L)
{
LNode* NewNode;//指向新结点的指针
LNode* TailNode = L;//指向尾结点的指针
ElemType NewNode_data;//新结点的data域
while (TailNode->next != NULL)
{
TailNode = TailNode->next;
}
printf("Please enter anumber(9999 means the end):");
scanf_s("%d", &NewNode_data);
while (NewNode_data != 9999)
{
//进行插入操作
NewNode = (LNode*)malloc(sizeof(LNode));
NewNode->data = NewNode_data;
NewNode->next = NULL;
TailNode->next = NewNode;
TailNode = NewNode;
L->data++;
printf("Please enter anumber(9999 means the end):");
scanf_s("%d", &NewNode_data);
}
return true;
}
int main()
{
LinkList L;//L是一个指针,还没有赋值实体化
L = (LNode*)malloc(sizeof(LNode));//放在这,若放在上面L指向NULL,没有指向它之前开辟的空间
InitLinkList(L);
//HeadInsertLinkList(L);
//PrintLinkList(L);
TailInsertLinkList(L);
PrintLinkList(L);
return 0;
}
9.单链表的按位查找
LNode* GetElem(LinkList L, int i)//L是所查链表,i是第i个位序
{
//判断i的合法性
if (i == 0)
{
printf("The Linklist's element you are looking for does not exist!\nReturn the head pointer of the Linklist!\n");
return L;
}
if (i<1 || i>L->data)
{
printf("The Linklist's element you are looking for does not exist!\nReturn NULL\n");
return NULL;
}
//查找数据元素
LNode* p = L;
for (int j = 0; j < i; j++)
{
p = p->next;
}
return p;
}
int main()
{
LinkList L;//L是一个指针,还没有赋值实体化
L = (LNode*)malloc(sizeof(LNode));//放在这,若放在上面L指向NULL,没有指向它之前开辟的空间
InitLinkList(L);
TailInsertLinkList(L);
PrintLinkList(L);
printf("L[4]=%d", GetElem(L, 4)->data);
return 0;
}
10.单链表的按值查找
LNode* LocateElem(LinkList L, ElemType e)
{
if (!L->next)
{
printf("This Linklist is empty!\n");
return L;
}
LNode* p = L;
while (p->next)
{
p = p->next;
if (p->data == e)
return p;
}
printf("The Linklist's element you are looking for does not exist!\n");
return NULL;
}
int main()
{
LinkList L;//L是一个指针,还没有赋值实体化
L = (LNode*)malloc(sizeof(LNode));//放在这,若放在上面L指向NULL,没有指向它之前开辟的空间
InitLinkList(L);
TailInsertLinkList(L);
PrintLinkList(L);
printf("L[5]=%d", LocateElem(L, 5)->data);
return 0;
}
11.单链表的按位插入
bool LocalInserLinklist(LinkList L, int i, ElemType e)
{
//判断i的合法性
if (i<1 || i>(L->data + 1))
{
printf("The position of the element to be inserted is invalid!\n");
return false;
}
//插入新元素
LNode* p = GetElem(L, i - 1);
LNode* NewNode = (LNode*)malloc(sizeof(LNode));
NewNode->data = e;
NewNode->next = p->next;
p->next = NewNode;
L->data++;
return true;
}
int main()
{
LinkList L;//L是一个指针,还没有赋值实体化
L = (LNode*)malloc(sizeof(LNode));//放在这,若放在上面L指向NULL,没有指向它之前开辟的空间
InitLinkList(L);
TailInsertLinkList(L);
PrintLinkList(L);
LocalInserLinklist(L, 5, 9999);
PrintLinkList(L);
return 0;
}
12.单链表的按位删除
bool LocalDeletElem(LinkList L, int i, ElemType* e)
{
//判断i的合法性
if (!L->next)
{
printf("The linklist is empty\n");
*e = 9999;
return false;
}
if (i<1 || i>(L->data))
{
printf("The position of the element to be deloeted is invalid!\n");
*e = 9999;
return false;
}
//删除指定元素
LNode* p = GetElem(L, i - 1);
LNode* q = p->next;//待删除元素
p->next = q->next;
*e = q->data;
free(q);
L->data--;
return true;
}
int main()
{
LinkList L;//L是一个指针,还没有赋值实体化
L = (LNode*)malloc(sizeof(LNode));//放在这,若放在上面L指向NULL,没有指向它之前开辟的空间
InitLinkList(L);
TailInsertLinkList(L);
PrintLinkList(L);
ElemType e;
LocalDeletElem(L, 2, &e);
printf("e=%d\n", e);
PrintLinkList(L);
return 0;
}
13.销毁单链表
bool DestoryLinkList(LinkList L)
{
int e;
while (L->data)
{
LocalDeletElem(L, 1 ,&e);
PrintLinkList(L);//可不加
}
free(L);
}
int main()
{
LinkList L;//L是一个指针,还没有赋值实体化
L = (LNode*)malloc(sizeof(LNode));//放在这,若放在上面L指向NULL,没有指向它之前开辟的空间
InitLinkList(L);
TailInsertLinkList(L);
PrintLinkList(L);
DestoryLinkList(L);
return 0;
}