线性表———单链表

//结点的赋值

LNode *p ;
p = (LNode *)malloc(sizeof(LNode));
p->data = 20;
p->next = NULL;

//1.遍历单链表,时间复杂度为o(n)

void  ergodic_SingleChainList(LNode* p)
{
	p = p->next;  //到1个结点
	while (1)
	{
		if (p == NULL)  break;    //判断链表的结束
		std::cout << p->data ;
		p = p->next;			//结点后移
	}
	std::cout<< endl;
}

2.动态的建立单链表:头插入法和尾插入法

// 结点的结构
//		typedef struct LNode {
//			int data;
//			struct LNode* next;
//		}LNode;
// 

//头插入法建表,时间复杂度为o(n)
// 即每次插入的结点都是第一个结点(L-5,4,3,2,1)

LNode* creat_Linkist()
{
	int aadata;
	LNode* p, * head;	//插入结点,头节点
	head = (LNode*)malloc(sizeof(LNode));  //用malloc()给头结点分配空间,free()删除结点
	head->next = NULL;
	while (1)
	{
		cin >> aadata;
		if (aadata == 9)  break;    //输入9,结束
		p = (LNode*)malloc(sizeof(LNode));	//用malloc()给插入结点分配空间,
		p->data = aadata;

		p->next = head->next;		//L--3--2--1--NULL
		head->next = p;				//  p
	}
	ergodic_SingleChainList(head);
	return head;
}

//尾插入法建表,时间复杂度为o(n)
// 即每次插入的结点都是最后一个结点(L-1,2,3,4,5)

LNode * creat_Linkist_w()
{
	int aadata;
	LNode* p, * head,*q;    //3个结点;
	head =p= (LNode*)malloc(sizeof(LNode));
	p->next = NULL;
	while (1)
	{
		cin >> aadata;
		if (aadata == 9)  break;
		q = (LNode*)malloc(sizeof(LNode));
		q->data = aadata;

		q->next = p->next;    //L--1--2--3--p--NULL
		p->next = q;		  //			  q
		p = q;				  //L--1--2--3--q--p--NULL

	}
	ergodic_SingleChainList(head);
	return head;
}

//3.单链表的查询
// 链表不是随机存取结构
//安序号查找,,仅当1<=i<=n时,合法。
//时间复杂度为o(n)

int Get_Elem(LNode* L,int i)
{
	int j=1;
	LNode* p;
	p = L->next;   //指向第一个结点

	while (p != NULL && j < i)  
	{
		p = p->next;	//移动p指针,j计数
		j++;
	}

	if (j != i) return -1;   //没找到或是i不合理
	else		return p->data;
}

//安值查找,时间复杂度为o(n)

LNode* Locate_Node(LNode* L, int key)
{
	LNode* p;
	p = L->next;

	while (p != NULL && p->data !=key)
		p = p->next;

	if (p->data == key)
		return p;
	else
	{
		std::cout<<"所要查找的结点不存在" << endl;
		return NULL;
	}
}

//4.单链表插入,时间复杂度为o(n)
//插入e值,到n结点。即插入到a[n-1]与a[n]之间,所以找到a[n-1]

void Insert_LNode(LNode * L, int n, int e)
{
	int j = 1;
	LNode * p, *q;
	p = L->next;	//指向第一个结点
	while (p != NULL && j < n - 1)
	{
		p = p->next;
		j++;
	}
	if (j != n - 1)   
		std::cout<<"n太大  或 n=0" << endl;
	else
	{
		q = (LNode*)malloc(sizeof(LNode));
		q->data = e;
		q->next = p->next;		//L--1--p--2--3--NULL
		p->next = q;			//	      q
	}
}

//5.单链表删除,时间复杂度为o(n)
//安序号删除
//删除n结点,找到L[n-1], L[n-1]结点有n结点的地址,改写L[n-1]的指针域,删除n结点
//1<= 序号 <=NULL合理

void Delete_LinList(LNode* L, int n)
{
	int j = 1;
	LNode *p, *q;
	p = L;
	q = L->next;

	while (p->next != NULL && j < n)
	{
		p = q;         //L[n-1]
		q = q->next;	//L[n]
		j++;
	}
	if (j != n)
		std::cout<<"n太大或为0" << endl;
	else
	{
		p->next = q->next;  //改写L[n-1]的指针域
		free(q);
	}
}

//安值删除

void Delete_LinList2(LNode* L, int key)
{
	LNode* p, * q;
	p = L;
	q = L->next;

	while (p->next != NULL && q->data!=key)
	{
		p = q;				//L[n-1]
		q = q->next;		//L[n]
	}
	if (q->data == key)
	{
		p->next = q->next;	//改写L[n-1]的指针域
		free(q);
	}		
	else
		std::cout << "所要删除的结点不存在" << endl;
}

//6.删除与key值相同的结点,时间复杂度为o(n)

void Delete_LinList_Node(LNode *L, int key)
{
	LNode* p, * q;
	p = L;
	q = L->next;
	while (q != NULL)
	{							//n=3
		if (q->data == key)		//L--1--2--3--4--5NULL
		{						//L--1--p--q--4--5--NULL
			p->next = q->next;   //L--1--pq--4--5--NULL
			free(q);			//L--1--p--4--5--NULL
			q = p->next;		//L--1--p--q--5--NULL
		}						//L--1--2--4--5--NULL
		else
		{						//L--p--q--3---4--5--NULL
			p = q;				//L--1--pq--3--4--5--NULL
			q = q->next;		//L--1--p--q--4--5--NULL
		}
	}
}

//7.删除 值 相同的结点,时间复杂度为o(n^2)
//基本思想:从第一个结点开始,对后面的结点进行检查,有相同删除。
// 在从第二个结点开始,对后面的结点进行检查,有相同删除。2层循环

void Delete_LinList_Value(LNode* L)
{
	LNode* p, * q, * ptr;
	p = L->next;	//指向第一个结点

	while (p!= NULL)	//检查所有结点
	{
		q = p;
		ptr = p->next;    //L--pq--ptr--3--4==5--NULL

		while (ptr!= NULL)  //检查一个结点 后的结点
		{
			if (p->data == ptr->data)
			{
				q->next = ptr->next;
				free(ptr);
				ptr = q->next;
			}
			else
			{
				q = ptr;
				ptr = ptr->next;
			}
		}
		p = p->next;
	}
}

//8.两个有序的链表的合并,时间复杂度为o(n+m)
//1 3 5 7 11
//2 4 6 8
//算法合并的链表为La,Lb,合并成Lc。
//分析:3个链表,4个指针,其中一个删除重复的结点。pa和pb结点比较大小,小的链接到pc,在后移结点;循环比较

LNode* Merge_LinkList(LNode* La, LNode* Lb)
{
	LNode* Lc, * pa, * pb, * pc, * ptr;
	Lc = La; pc = La; pa = La->next; pb = Lb->next;
	int a = 0, b = 0;
	while (pa != NULL && pb != NULL)  //判断链表的结束
	{
		if (pa->data < pb->data)  //pa小,链接到pc,pa后移
		{
			pc->next = pa; pc = pa;  pa = pa->next;
			continue;
		}
		if (pa->data > pb->data) //pb小,链接到pc,pb后移
		{
			pc->next = pb; pc = pb;  pb = pb->next; 
			continue;
		}
		if (pa->data == pb->data)	//pa==pb,pa链接到pc,删除pb。pa、pb都后移
		{
			pc->next = pa; pc = pa;  pa = pa->next;
			ptr = pb;   pb = pb->next;  free(ptr);
			continue;
		}
	}
	if (pa != NULL)
		pc->next = pa;
	else
		pc->next = pb;
	free(Lb);
	return Lc;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值