【数据结构】单链表 创建 插入 删除 查找 完整代码

3.1 单链表

3.1.1 定义

  • 注:

    元素离散的分布在存储空间中,所以单链表是非随机存取的存储结构。

    即不能直接找到表中某个特定的结点,需要从表头开始遍历,依次查找。

  • 定义的代码

    typedef struct LNode
    {
    	ElemType data;//每个节点存放一个数据元素
    	struct LNode* next;//指向下一个节点
    }LNode,*LinkList;
    
  • 头结点和头指针

  • 初始化

    分为带或不带头结点的初始化。

    一般用带头结点的链表,会使后续操作方便。

    • 不带头结点的初始化

      bool InitList(LinkList &L)
      {
          L=NULL;
          return ture;
      }
      
    • 带头结点的初始化

      bool InitList(LinkList& L)
      {
      	L = (LNode*)malloc(sizeof(LNode));//分配一个头节点
      	if (L == NULL)return false;//分配失败
      	L->next = NULL;
      	return true;
      }
      
3.1.2 建立
1)头插法建立单链表

在链表表头插入新结点。

  • 步骤

    1.将要插入结点的指针指向 原第一个结点;

    2.将头结点指针指向 要插入的结点。

//头插法建立单链表
LinkList List_HeadInsert(LinkList& L)
{
	LNode* s;
	int x;
	InitList(L);//初始化
	scanf_s("%d", &x);//输入结点值
	//插入表中
	while (x != 9999)//9999表示结束
	{
		//创建新结点
		s = (LNode*)malloc(sizeof(LNode));
		s->data = x;
		s->next = L->next;//新结点指针域指向原来的第一个结点
		//头结点指向新结点
		L->next = s;
		scanf_s("%d", &x);
	}
	return L;
}
2)尾插法建立单链表

在链表末尾插入新结点。

  • 步骤

    1.将尾结点的指针指向新结点;

    2.更新尾指针(新尾指针变成新结点)。

//尾插法建立链表
LinkList List_TailInsert(LinkList& L)
{
    LNode* s, * r = L;//r为表尾指针
    int x;
    scanf_s("%d", &x);//输入结点值
    //插入表中
    while (x != 9999)//9999表示结束
    {
        //创建新结点
        s = (LNode*)malloc(sizeof(LNode));
        s->data = x;
        //表尾指针指向新结点
        r->next = s;
        //更新表尾结点
        r = s;
        scanf_s("%d", &x);
    }
    r->next = NULL;//尾结点指针置空
    return L;
}
3.1.3 插入
  • 步骤

    1.查找插入位置的前驱结点;

    2.将插入结点的指针 指向 插入位置的后驱结点;

    3.将前驱结点的指针指向 插入结点。

//在表L中的第i个位置上插入指定元素e
bool ListInsert(LinkList& L, int i, ElemType e)
{
	if (i < 1)return false;
	LNode* p;//指针指向当前扫描到的节点
	int j = 0;//当前p指向的是第几个节点
	//查找第i个位置
	p = L;//L指向头节点,头节点是第0个节点
	while(p!=NULL&&j<i-1)
	{
		p = p->next;
		j++;
	}
	if (p == NULL)
		return false;
	LNode* s = (LNode*)malloc(sizeof(LNode));
	s->data = e;
	s->next = p->next;
	p->next = s;
	return true;
}
3.1.4 删除
  • 步骤

bool ListDelete(LinkList& L, int i, ElemType& e)
{
	if (i < 1)return false;

	LNode* p;//指针p指向当前扫描到的结点
	int j = 0;//当前p指向的是第几个结点

	//循环找到第i-1个结点
	p = L;//指向头结点
	while (p != NULL && j < i - 1) {
		p = p->next;
		j++;
	}
	//i值不合法
	if (p == NULL||p->next==NULL)return false;

	LNode* q = p->next;//令q指向被删除结点
	e = q->data;//用e返回元素的值
	p->next = q->next;//将*q结点从链中断开
	free(q);//释放结点存储空间
	return true;
}
3.1.5 查找
1)按序号查找结点
//按序号查找结点
LNode* GetElem(LinkList L, int i)
{
	if (i < 1)return NULL;
	int j = 1;
	LNode* p = L->next;//第1个结点指针赋给p
	while (p != NULL && j < i)
	{
		p = p->next;
		j++;
	}
	return p;
}
2)按值查找结点
//按值查找
LNode* LocateElem(LinkList L, ElemType e)
{
	LNode* p = L->next;
	while (p != NULL && p->data != e)
	{
		p = p->next;
	}
	return p;
}

* 完整代码

#include<stdio.h>
#include <malloc.h>
#include<time.h>//用于生成随机数
#include<stdlib.h>
#define ElemType int

//---------------定义---------------
typedef struct LNode
{
	ElemType data;//每个节点存放一个数据元素
	struct LNode* next;//指向下一个节点
}LNode,*LinkList;


初始化不带头节点的单链表
//bool InitList(LinkList& L) {
//	L = NULL;
//	return true;
//}
不带会麻烦

//初始化带头节点的单链表
bool InitList(LinkList& L)
{
	L = (LNode*)malloc(sizeof(LNode));//分配一个头节点
	if (L == NULL)return false;
	L->next = NULL;
	return true;
}


//---------------建立单链表---------------

//头插法建立单链表
LinkList List_HeadInsert(LinkList& L)
{
	int m;
	printf("\n1.手动输入\n2.自动生成\n");
	scanf_s("%d", &m);

	if (m == 1)
	{
		LNode* s;
		int x;
		scanf_s("%d", &x);//输入结点值
		//插入表中
		while (x != 9999)//9999表示结束
		{
			//创建新结点
			s = (LNode*)malloc(sizeof(LNode));
			s->data = x;
			s->next = L->next;//新结点指针域指向原来的第一个结点
			//头结点指向新结点
			L->next = s;
			scanf_s("%d", &x);
		}
		return L;
	}
	else if (m == 2)
	{
		LNode* s;
		int n = 10;//结点个数
		srand(time(0));//初始化随机数种子
		while (n--)
		{
			//创建新结点
			s = (LNode*)malloc(sizeof(LNode));
			s->data = rand() % 100 + 1;//随机产生100以内的数
			s->next = L->next;
			L->next = s;
		}
	}
	else
	{
		printf("请重新输入!\n");
		List_HeadInsert(L);
	}
	
}

//尾插法建立链表
LinkList List_TailInsert(LinkList& L)
{
	int m;
	printf("\n1.手动输入\n2.自动生成\n");
	scanf_s("%d", &m);

	if (m == 1)
	{
		LNode* s, * r = L;//r为表尾指针
		int x;
		scanf_s("%d", &x);//输入结点值
		//插入表中
		while (x != 9999)//9999表示结束
		{
			//创建新结点
			s = (LNode*)malloc(sizeof(LNode));
			s->data = x;
			//表尾指针指向新结点
			r->next = s;
			//更新表尾结点
			r = s;
			scanf_s("%d", &x);
		}
		r->next = NULL;//尾结点指针置空
		return L;
	}
	else if (m == 2)
	{
		LNode* s,*r=L;
		int n = 10;//结点个数
		srand(time(0));//初始化随机数种子
		while (n--)
		{
			//创建新结点
			s = (LNode*)malloc(sizeof(LNode));
			s->data = rand() % 100 + 1;//随机产生100以内的数
			r->next = s;
			r = s;
		}
		r->next = NULL;
		return L;
	}
	else
	{
		printf("请重新输入!\n");
		List_TailInsert(L);
	}
}


//---------------插入-----------------
//在表L中的第i个位置上插入指定元素e
bool ListInsert(LinkList& L, int i, ElemType e)
{
	if (i < 1)return false;
	LNode* p;//指针指向当前扫描到的节点
	int j = 0;//当前p指向的是第几个节点
	//查找第i个位置
	p = L;//L指向头节点,头节点是第0个节点
	while(p!=NULL&&j<i-1)
	{
		p = p->next;
		j++;
	}
	if (p == NULL)
		return false;
	LNode* s = (LNode*)malloc(sizeof(LNode));
	s->data = e;
	s->next = p->next;
	p->next = s;
	return true;
}


//---------------删除----------------
bool ListDelete(LinkList& L, int i, ElemType& e)
{
	if (i < 1)return false;

	LNode* p;//指针p指向当前扫描到的结点
	int j = 0;//当前p指向的是第几个结点

	//循环找到第i-1个结点
	p = L;//指向头结点
	while (p != NULL && j < i - 1) {
		p = p->next;
		j++;
	}
	//i值不合法
	if (p == NULL||p->next==NULL)return false;

	LNode* q = p->next;//令q指向被删除结点
	e = q->data;//用e返回元素的值
	p->next = q->next;//将*q结点从链中断开
	free(q);//释放结点存储空间
	return true;
}


//---------------查找----------------
//按序号查找结点
LNode* GetElem(LinkList L, int i)
{
	if (i < 1)return NULL;
	int j = 1;
	LNode* p = L->next;//第1个结点指针赋给p
	while (p != NULL && j < i)
	{
		p = p->next;
		j++;
	}
	return p;
}

//按值查找
LNode* LocateElem(LinkList L, ElemType e)
{
	LNode* p = L->next;
	while (p != NULL && p->data != e)
	{
		p = p->next;
	}
	return p;
}


void List_print(LinkList& L)
{
	LinkList t = L->next;
	while (t->next != NULL)
	{
		printf("%d,", t->data);
		t = t->next;
	}
	printf("%d\n", t->data);
}

void PutMenu()
{
	printf("\n----------菜单----------\n");
	printf("1.头插法创建单链表\n2 尾插法创建单链表\n");
	printf("3.插入元素\n");
	printf("4.删除元素\n");
	printf("5.按序号查找结点\n");
	printf("6.按值查找结点\n");

	printf("请选择想执行的操作:\n");
}


int main()
{
	LinkList L1;
	InitList(L1);

	//---------------菜单---------------
	PutMenu();
	int x;
	while (~scanf_s("%d", &x))
	{
		if (x == 1)
		{
			//头插法创建单链表
			List_HeadInsert(L1);
			List_print(L1);
		}
		else if (x == 2)
		{
			//尾插法创建单链表
			List_TailInsert(L1);
			List_print(L1);
		}
		else if (x == 3)
		{
			int pos, e;
			printf("请输入要插入的位置和元素:\n");
			scanf_s("%d %d", &pos, &e);
			ListInsert(L1, pos, e);
			List_print(L1);
		}
		else if (x == 4)
		{
			int pos, e;
			printf("请输入要删除的元素位置:\n");
			scanf_s("%d", &pos);
			ListDelete(L1, pos, e);
			printf("被删元素:%d\n",e);
			List_print(L1);
		}
		else if (x == 5)
		{
			LNode* p;
			int n;
			printf("请输入需要查找的序号:\n");
			scanf_s("%d", &n);
			p = GetElem(L1, n);
			printf("查找结点的值:%d", p->data);
		}
		else if (x == 6)
		{
			LNode* p;
			int n;
			printf("请输入需要查找的结点值:\n");
			scanf_s("%d", &n);
			p =LocateElem(L1, n);
			printf("success!");
		}
		PutMenu();
	}
	return 0;
}
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值