单链表(王道数据结构)

一、单链表的构成

链表:由一个个结点构成,每个结点一般采用结构体的形式组织,一个结点分为数据域和指针域
数据域:存放各种实际的数据,如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;
}
  • 12
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值