单链表算法实现
单链表的基本操作实现
先说点题外话:本科是一所双非院校,因为已经在准备考研了,所以不得不回头重新拿起这些最基本的数据结构知识,每重新看一次都会有一些新的理解,因为在校期间说实话数据结构这些基本知识确实学的不好,曾经有一段时间一直在逃避,可能不如其他大佬那么精简,但是后来发现计算机这一行算法是逃不掉的,加上从入学就一直想考研,重新买了王道的书,一点一点的扣这些基本算法,希望能把每个点吃透,也让别人看的舒服一点,实践远大于理论,这是我学这个专业最为赞同的一句话,无论什么时候都要实操这些东西,所以本着这些我一次又一次在机器上跑这些代码,就是为了让自己的知识更为扎实牢固一点,希望我的努力能或多或少帮助到你。
这些算法都是基于带头结点的链表实现的,因为时间有限,所以不带头结点的就不放上来了,当然很多操作可能有我没想到的地方,或许可以变形更为精简,如有错误欢迎各位批评指正
1.初始化单链表
//单链表的初始化
int InitList(LinkList* L) //引用类型指针形参// 
{
	(*L) = (LinkList)malloc(sizeof(LNode));  //头结点分配空间// 
	(*L)->next = NULL;               //头结点指针域置空//                          
	if (L)
		printf("Finish\n");
	else
		printf("Error\n");
	return Ok;
}
2.头插法创建单链表
int CreateList_1(LinkList* L, int n) //引用类型指针形参// 
{
	printf("逆序输入\n");
	int i;
	LinkList p;
	(*L) = (LinkList)malloc(sizeof(LNode));
	(*L)->next = NULL;
	for (i = n; i > 0; i--)
	{
		p = (LNode*)malloc(sizeof(LNode));
		scanf("%d", &p->data);
		p->next = (*L)->next;
		(*L)->next = p;
	}
	return Ok;
}
3.尾插法创建单链表
//尾插法构建链表// 
int CreateList_2(LinkList* L, int n) //引用类型指针形参//
{
	int i;
	printf("正序输入\n");
	LinkList p, r;
	(*L) = (LinkList)malloc(sizeof(LNode));
	(*L)->next = NULL;
	r = (*L);
	for (i = 0; i < n; i++)
	{
		p = (LinkList)malloc(sizeof(LNode));
		scanf("%d", &p->data);
		p->next = NULL;
		r->next = p;
		r = p;
	}
	return Ok;
}
4.按位查找单链表
//按位序查找
int GetElem2(LinkList L, int i)
{
	LNode* p = L;
	if (i < 0)
		printf("查找位置不合法,查找失败!");
	int j = 0;
	while (p != NULL && j < i)
	{
		p = p->next;
		j++;
	}
	return p;
}
5.按值查找
//按值查找
int GetElem(LinkList L, int i, Elemtype* e)
{
	int j;
	LinkList p;     /* 声明一结点p */
	p = L->next;     /* 让p指向链表L的第一个结点 */
	j = 1;      /*  j为计数器 */
	while (p && j < i)  /* p不为空或者计数器j还没有等于i时,循环继续 */
	{
		p = p->next;  /* 让p指向下一个结点 */
		++j;
	}
	if (!p || j > i)
		return Error;  /*  第i个元素不存在 */
	*e = p->data;   /*  取第i个元素的数据 */
	return Ok;
}
6.单链表的插入操作
//单链表的插入(按位序插入)
int InsertList(LinkList L, int i, Elemtype e)
{
	if (i < 1)
	printf("插入位置非法,插入失败!");//这里的插入是按照位置插入,并非结点下标值。所以从第一个位置插入
	LNode* p, * x;
	p = L;
	
	int j = 0;//头节点为第0个结点,没有数据
	while (p!=NULL&&j<i-1)//遍历找到插入位置的前一个元素
	{
		p = p->next;
		j++;
	}
	if (!p || j > i - 1)
		return Error;
	x = (LNode*)malloc(sizeof(LNode));
	x->data = e;
	x->next = p->next;
	p->next = x;
	printf("插入数据成功");
}
7.单链表的删除
//单链表的删除操作
int DeleteNode(LinkList L, int i, Elemtype e)
{
	LNode* p = L;
	//找到待删除节点的前驱结点,让前驱结点指向待删除节点的后继节点。释放结点内存空间
	int j = 0;
	while (p != NULL&&j<i-1)
	{
		p = p->next;
		j++;
	}
	if (!p || j > i - 1)//删除位置不合法
		return Error;
	LNode* q = p->next;//q指向被删除结点
	p->next = q->next;
	e = q->data;
	free(q);
}
8.单链表的逆置
//单链表的逆置
void Travserve(LinkList L)
{
	LinkList p = L->next;
	L->next = NULL;
	LinkList q;
	while (p)
	{
		q = p->next;
		p->next = L->next;
		L->next = p;
		p = q;
	}
}
9.利用后插实现结点的前插
//前插操作的变形,
int PriorInsert(LinkList *L, int i,LNode* p, LNode* s)//s为待插入节点,
{
	//调用查找函数先找到插入该结点的前驱结点
	
	GetElem2(L, i);//查找p结点
	s->next = p->next;
	p->next = s;
	//交换数据域
	Elemtype temp=p->data;
	p->data = s->data;
	s->data = temp;
	printf("插入成功");
}
10.清空单链表
//清空单链表
void clear(LinkList L)
{
	LinkList p, q;
	p = L->next;
	while (p)
	{
		q = p->next;
		free(p);
		p = q;
	}
	L->next = NULL;
	printf("链表已清空");
}
11.判空操作
//判空
void Empty(LinkList L)
{
	if (L->next == NULL)
	{
		printf("链表为空链表");
	}
	else {
		printf("链表不为空");
	}
}
    每个牛b的人物背后都有一段你看不见的苦b岁月,只有像sb一样的坚持,终将会有牛b的人生

 
                
             
         浙公网安备 33010602011771号
浙公网安备 33010602011771号