线性表之链表(单链表)

线性表:由n(n>=0)个相同类型数据元素组成,并且可以 在任意位置进行插入和删除数据元素操作的有限序列。

单链表:它是一种链式存储的线性表,用一组地址任意的存储单元存放线性表        的数据元素,称存储单元为一个节点。



代码实现:

list.h

#include<stdio.h>
#include<stdlib.h>
#include<cassert>

typedef int DataType;
typedef struct node
{
	DataType data;
	struct node* next;

}Node, *pNode, *pList;


pNode Create(DataType d);  //创建链表
void PushBack(pList p_list, DataType d);//尾插
void PrintList(pList p_list);//打印
void PrintListrecur(pList p_list); //递归倒叙打印链表
void PrintListBack(pList p_list);//倒序打印
pNode Find(pList p_list, DataType x); //查找
void DeleteNohead(pNode pos);//删除无头节点的非尾节点
void InsertNohead(pNode pos,DataType d);///插入无头结点的非头结点
pNode JosephList(pList p_list); //链表环化
pNode JosepListK(pList p_list, int k);
pNode Lnverse(pList p_list);//逆置链表
pNode MergeList(pList p_list1, pList p_list2);//合并两个链表
pNode QsortMergeList(pList p_list1, pList p_list2);//合并有序两个链表之后依然有序
pNode FindMidNode(pList p_list);//查找中间节点
pNode FindThelastK(pList p_list, int k);//查找倒数第K个节点


#endif //__LIST_H__
list.c
#include"List.h"


pNode Create(DataType d)//创建
{
	pNode p_list = (pNode)malloc(sizeof(Node));
	if (p_list == NULL)
	{
		return NULL;
	}
	p_list->data = d;
	p_list->next = NULL;
	return p_list;

}

void PushBack(pList p_list, DataType d)//尾插
{
	pNode p1 = p_list;
	pNode p2 = NULL;
	p2 = (pNode)malloc(sizeof(Node));
	if (p2 == NULL)
	{
		return;
	}
	while (p1->next != NULL)
	{
		p1 = p1->next;
	}
	p2->data = d;
	p1->next = p2;
	p2->next = NULL;
}

void PrintList(pList p_list)//打印
{
	assert(p_list);
	while (p_list->next != NULL)
	{
		printf("%d->", p_list->data);
		p_list = p_list->next;
	}

	printf("%d->NULL\n", p_list->data);
}

//一.从尾到头打印链表
void PrintListrecur(pList p_list) //递归倒叙打印链表
{
	if (p_list != NULL)
	{
		if (p_list->next != NULL)
		{
			PrintListrecur(p_list->next);
		}
		printf("%d->", p_list->data);     
	}
	
}

pNode l = NULL;
void PrintListBack(pList p_list)  //倒序打印
{
	pNode p;
	p = p_list;
	while (p != NULL)
	{
		while (p != l)
		{
			pNode q = NULL;
			q = p;

			if (q->next == l)
			{
				printf("%d->", p->data);
				break;
			}
			p = p->next;
		}
		l = p;
		if (l == p_list)
			break;
		p = p_list;
	}
	printf("\n");
}

//二.删除无头结点的非尾节点(不能遍历链表)
pNode Find(pList p_list, DataType x)  //查找
{
	pNode p, q;
	p = p_list;
	q = NULL;
	while (p->next->data != x&&p->next != NULL)
	{
		p = p->next;
		if (p->next == NULL)
		{
			printf("没有找到\n");
			return NULL;
		}
	}
	printf("找到了\n");
	return (p = p->next);
}

void DeleteNohead(pNode pos) //删除无头节点非尾节点
{
	assert(pos);
	pNode ptmp1 = NULL;
	pNode ptmp2 = NULL;
	ptmp1 = pos->next;
	ptmp2 = ptmp1->next;
	DataType tmp=pos->data;
	pos->data = ptmp1->data;
	ptmp1->data = tmp;
	pos->next = ptmp2;
	ptmp1->next = NULL;
	free(ptmp1);
}

//三.在无头单链表的一个非头节点前插入一个节点
void InsertNohead(pNode pos,DataType d) //插入无头结点的非头结点前
{
	assert(pos);
	pNode ptmp1 = NULL;
	pNode ptmp2 = NULL;
	ptmp2 = pos->next;
	ptmp1 = (pNode)malloc(sizeof(Node));
	if (ptmp1 == NULL)
		return;
	ptmp1->data = d;
	pos->next = ptmp1;
	ptmp1->next = ptmp2;
	DataType tmp = pos->data;
	pos->data = ptmp1->data;
	ptmp1->data = tmp;
}

//四.单链表实现约瑟夫环(JosephCircle)
pNode JosephList(pList p_list) //链表环化
{
	pNode p = p_list;
	while (p_list->next != NULL)
	{
		p_list = p_list->next;
	}
	p_list->next = p;
	return p;
}

pNode JosepListK(pList p_list, int k)
{
	int i = 0;
	for (i = 0; i < k - 1; i++)
	{
		p_list = p_list->next;
	}
	pNode p1 = p_list;
	pNode p2 = p_list->next;
	pNode p3 = p_list->next->next;
	p1->next = p3;
	free(p2);
	if (p1->next == p1)
		return p1;
	JosepListK(p3, k);
}

//五.链表逆置
pNode Lnverse(pList p_list)//逆置链表
{
	assert(p_list);
	pNode pHead = NULL;
	pNode p1 = p_list;
	pNode pt = NULL;
	while (p1 != NULL)
	{
		pNode p2 = p1->next;
		if (p2 == NULL)
			pHead = p1;
		p1->next = pt;
		pt = p1;
		p1 = p2;
	}
	return pHead;

}

//六.合并两个有序链表, 合并后依然有序
pNode MergeList(pList p_list1, pList p_list2)//合并两个链表
{
	assert(p_list1);
	assert(p_list2);

	pNode p = p_list1;
	while (p->next != NULL)
	{
		p = p->next;
	}
	p->next = p_list2;
	return p_list1;
}

pNode QsortMergeList(pList p_list1, pList p_list2)//合并有序两个链表之后依然有序
{
	pNode newhead = NULL;
	if ((p_list1 == NULL) && (p_list2 != NULL))
	{
		return p_list2;
	}
	if ((p_list1 != NULL) && (p_list2 == NULL))
	{
		return p_list1;
	}
	if ((p_list1->data) >= (p_list2->data))
	{
		newhead = p_list1;
		newhead->next = QsortMergeList(p_list1->next, p_list2);
	}
	else
	{
		newhead = p_list2;
		newhead->next = QsortMergeList(p_list1, p_list2->next);
	}
	return newhead;
}

//七.查找单链表的中间节点,要求只能遍历一次链表
pNode FindMidNode(pList p_list)//查找中间节点
{
	assert(p_list);
	pNode p1 = p_list;
	pNode p2 = p_list;
	while (p2->next->next != NULL)
	{
		p1 = p1->next;
		p2 = p2->next->next;
		if (p2->next == NULL)
		{
			return p1;
		}
	}
	return p1;
}

//八.查找单链表的倒数第k个节点,要求只能遍历一次链表
pNode FindThelastK(pList p_list, int k)//查找倒数第K个节点
{
	pNode p1 = p_list;
	pNode p2 = p_list;
	int i = 0;
	for (i = 0; i < k - 1; i++)
	{
		p2 = p2->next;
	}
	while (p2->next != NULL)
	{
		p2 = p2->next;
		p1 = p1->next;
	}
	return p1;
}
test.c 部分测试
#include"List.h"

void test1()
{
	pNode p = NULL;

	p=Create(5);
	PushBack(p, 4);
	PushBack(p, 3);
	PushBack(p, 2);
	PushBack(p, 1);
	PushBack(p, 0);
	PrintList(p);
	PrintListrecur(p);
	printf("\n");
	PrintListBack(p);
	pNode pos=Find(p, 2);
	DeleteNohead(pos);
	PrintList(p);
}
void test2()
{
	pNode p = NULL;

	p = Create(5);
	PushBack(p, 4);
	PushBack(p, 2);
	PushBack(p, 1);
	PushBack(p, 0);
	PrintList(p);
	pNode pos=Find(p, 2);
	InsertNohead(pos, 3);
	PrintList(p);
}

int main()
{
//	test1();
	test2();
	return 0;

}



 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

멋진

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值