链表的创建、遍历、查找、插入、删除

温馨提示

可以画图来模拟链表操作,其中要注意指针的指向,注意指针赋值的先后关系。

一、链表的创建(头插法、尾插法)

1、准备工作:
引入头文件及创建基本数据结构

#include<stdio.h>
#include<stdlib.h>	//提供 malloc 和 free 函数

typedef struct node{ //typedef 是重新定义数据类型 struct node
	int data;
	struct node *next;
}NODE,*PNODE;

2、头插法:

//头插法创建链表
PNODE HeadInsert(int n)
{
	int i,temp;
	PNODE head,p;
	head = (PNODE)malloc(sizeof(NODE));
	head->next = NULL;
	for(i = 0;i < n;i++)
	{
		scanf("%d",&temp);
		p = (PNODE)malloc(sizeof(NODE));
		p->data = temp;
		p->next = NULL;
		//头插法,顺序不能换 
		p->next = head->next;
		head->next = p;
		
	}
	return head; 
 } 
 

输入数据的顺序和表中数据的顺序是相反的。

输入顺序: 0 1 2 3 4 5 6 7 8 9
表中顺序: 9 8 7 6 5 4 3 2 1 0
在这里插入图片描述
3、尾插法:

 //尾插法创建链表
PNODE TailInsert(int n)
{
	int i,temp;
	PNODE head,p,tail;
	head = (PNODE)malloc(sizeof(NODE));
	head->next = NULL;
	tail = head; //tail指向尾节点,现在尾节点是head 
	for(i = 0;i < n;i++)
	{
		scanf("%d",&temp);
		p = (PNODE)malloc(sizeof(NODE));
		p->data = temp;
		p->next = NULL;
		//尾插法,节点增加后,尾指针要再次指向尾节点 
		tail->next = p;
		tail = p; //也可以 tail = tail->next; 
	}
	return head; 
 } 

在这里插入图片描述

二、链表的遍历与查找

1、顺序查找并打印链表

void PrintList(PNODE L) //顺序打印表中数据
{
	PNODE p;
	p = L;
	if(p->next == NULL)	//这种是含头节点链表的输出方法
	{
		printf("表中没有数据,只有一个头节点!\n");
		return ;
	}
	p = p->next;	//p指针指向第一个数据节点 
	while(p != NULL)
	{
		printf("%d ",p->data);
		p = p->next;	//p指针指向下一个数据节点 
	}
}

2、按值查找

//按值查找 
PNODE ValueSearch(PNODE Head,int key)
{
	PNODE p;
	p = Head;
	if(p->next == NULL)
	{
		printf("表中没有数据,只有一个头节点!\n");
		return Head;
	}
	p = p->next;	//p指针指向第一个数据节点 
	while(p != NULL)
	{
		if(p->data == key)
			return p;	//查找成功,返回指向该节点的指针 
			
		p = p->next;	//p指针指向下一个数据节点 
	}
	return NULL;	//查找失败,返回NULL 
/*	简洁版
PNODE ValueSearch(PNODE Head,int key)
{ 
	PNODE p = Head->next;	//指向第一个节点
	while(p != NULL && p->data != key)	
		p = p->next;	//p指针指向下一个数据节点 
	return p;	//查找成功,返回对应节点;查找失败,返回NULL 
}
*/ 
}

3、按序号查找

//按序号查找 
PNODE NumberSearch(PNODE Head,int n)
{
	int i;
	PNODE p;
	p = Head;
	if(p->next == NULL || n == 0)
	{
		printf("表中没有数据,只有一个头节点!\n");
		return Head;
	}
	p = p->next;	//p指针指向第一个数据节点 
	i = 1;			//这里不把头节点算进来 
	while(p != NULL)
	{
		if(i == n)
			return p;	//查找成功,返回指向该节点的指针 
			
		p = p->next;	//p指针指向下一个数据节点 
		i++; 
	}
	return NULL;	//查找失败,返回NULL 
}

三、链表的插入

void Insert(PNODE Head,int n,int key)
{
	int i;
	PNODE p,q;
	p = Head;
	if(p->next == NULL || n == 0)
	{
		printf("表中没有数据,只有一个头节点!\n");
		return ;
	}
	p = p->next;	//p指针指向第一个数据节点 
	i = 1;			//这里不把头节点算进来 
	while(p != NULL)
	{
		if(i == n)
		{
			q = (PNODE)malloc(sizeof(NODE));
			q->data = key;
			//顺序不能换 
			q->next = p->next;
			p->next = q;
			
			printf("插入成功!\n");
			return ;
		}		
		p = p->next;	//p指针指向下一个数据节点 
		i++; 
	}
	 
}

四、链表的删除

//删除第i个元素 
void Delete(PNODE Head,int n) 
{
	int i;
	PNODE p,q;
	p = Head;
	if(p->next == NULL || n == 0)
	{
		printf("表中没有数据,只有一个头节点!\n");
		return ;
	}
	p = p->next;	//p指针指向第一个数据节点 
	i = 1;			//这里不把头节点算进来 
	while(p != NULL)
	{
		if(i == n-1 && p->next !=NULL)	//找到删除节点的前一个节点 ,p指向它 
		{
			//顺序不能变 ,单向链表不能直接找到上一节点 
			q = p->next;	// q 指向删除节点 
			free(p->next);		//释放删除节点 
			p->next = q->next; 		//前一节点指向后一节点 
			
			printf("删除成功!\n");
			return ;
		}		
		p = p->next;	//p指向下一个节点 
		i++; 
	}
}