【笔试面试】链表相关操作

/***************链表各类操作*********************
*** 1 链表的基本操作:建立、销毁、插入、删除(两种删除方法)
*** 2 链表的访问操作:遍历,反向遍历,逆置,链表的查找
*** 3 环形链表--约瑟夫环问题
*** 4 环形链表的各种形式,判断是否是环形链表,环形链表的入口地址
*** 5 链表是否相交,相交的位置
*** 6 链表的查找:倒数第k个元素,中间的元素
*** 7 两个有序链表的合二为一
***
***
***
***
***
*************************************************/

//=========使用模板编写????===============

#include <iostream>
#include <string>
#include <vector>
#include <stack>

using namespace std;

struct Node
{
	int m_data;
	Node * next;
};
typedef Node* list;

//链表的初始化 创建表头
list initList()
{
	list head = new Node;
	head->next = NULL;
	return head;
}

//链表的销毁
void destroyList(list &head)//此处需要引用,把每个结点销毁 指向NULL
{
	 //temp= head->next;
	while(head)
	{
		list temp = head->next;
		delete head;
		head = NULL;
		head = temp;
	}

}

//链表的长度
int lenthList(list head)
{
	int length=0;
	while(head->next)
	{
		length++;
		head = head->next;
	}
	return length;
}

//顺序遍历一个链表
void traverseList(list head)
{
	list curr = head->next;
	while(curr)
	{
		cout<<curr->m_data<<" ";
		curr = curr->next;
	}
	cout<<endl;
}

//逆序遍历一个链表  --类似于中序遍历和后续遍历
void reTraverseList(list head)
{
	if(!head)
		return;
	reTraverseList(head->next);
	if (head->next)
	{
		cout<<head->next->m_data<<" ";
	}
	
}

//建立一个链表--头插法
list buildListHead()
{
	list head = initList();
	for (int i =0;i<10;++i)
	{
		list temp = new Node;
		temp->m_data = i;
		temp->next = head->next;
		head->next = temp;
	}
	//traverseList(head);
	cout<<endl;
	return head;
}

//建立一个链表--尾插法
list buildListTail()
{
	list head = initList();
	list curr = head;
	for (int i=0;i<10;++i)
	{
		list temp = new Node;
		temp->m_data = i;
		temp->next = curr->next;
		curr->next = temp;
		curr = temp;
	}
	//traverseList(head);
	//cout<<endl;
	return head;
}

// 插入一个结点
list insertNode(list & head,int pos,int value)//有可能影响第一个结点 若是没有头结点,则需要使用引用变量
{
	int k = pos;
	int lenth = lenthList(head);
	if (pos < 1 || pos > lenth+1)
	{
		cout<<"插入位置越界!!Error!!"<<endl;
		return head;
	}
	//尾插 找到前一个位置,往它的后面插
	list temp = new Node;
	temp->m_data = value;

	list curr = head;
	while(pos-1)
	{
		curr = curr->next;
		pos--;
	}
		
	temp->next = curr->next;
	curr->next = temp;
	cout<<"在位置"<<k<<"处插入节点之后的链表:"<<ends;
	traverseList(head);
	cout<<endl;
	return head;
}


//删除一个结点--普通做法,找到其前面一个位置 干掉他
list deleteNode(list head,int pos)
{
	int k = pos;
	int length = lenthList(head);
	if (pos<1 || pos >length)
	{
		cout<<"删除的位置越界咯!!Error!!"<<endl;
		return head;
	}
	list curr = head;
	while(pos-1)
	{
		pos--;
		curr = curr->next;
	}
	list temp = curr->next;
	curr->next = temp->next;
	delete temp;
	temp = NULL;
	cout<<"删除位置为"<<k<<"的结点之后的链表:"<<ends;
	traverseList(head);
	cout<<endl;
	return head;
}

//删除结点-- O(1)时间  适用于删除非最后一个结点的结点
// list deleteNodeFast(list head,int pos)
// {
// 	int length = lenthList(head);
// 	if (pos<1 || pos>length)
// 	{
// 		cout<<"删除位置过界:"<<endl;
// 		return head;
// 	}
// 	if (pos == length)
// 	{
// 		list curr = head;
// 		while(pos-1)
// 		{
// 			pos--;
// 			curr  = curr->next;
// 		}
// 		list temp = curr->next;
// 		curr->next = temp->next;
// 		delete temp;
// 		temp = NULL;
// 		return head;
// 	}
// 	//hah 参数写错了
// }
//删除结点--按结点删除
list deleteNodeFast(list head,list node)
{
	cout<<"按结点删除结点:"<<endl;
	if (!node)
	{
		return head;
	}
	if (! node->next)
	{
		list pre = head;
		list curr = head->next;
		while(curr->next)
		{
			pre = curr;
			curr = curr->next;
		}
		pre->next = curr->next;
		delete node;
		node = NULL;
		traverseList(head);
		cout<<endl;
		return head;
	}
	list temp = node->next;
	node->m_data = temp->m_data;
	node->next = temp->next;
	delete temp;
	temp = NULL;
	traverseList(head);
	cout<<endl;
	return head;
}

//查找链表中某一结点
list searchList(list head,int data)
{
	list curr = head->next;
	while(curr && curr->m_data!= data)
	{
		curr = curr->next;
	}
	if (!curr)
	{
		return NULL;
	}
	else
		return curr;
}

//判断是否是循环链表
bool isCycleList(list head)
{
	list fast = head;
	list slow = head;
	while(fast->next && fast->next->next)
	{
		fast = fast->next->next;
		slow = slow->next;
		if (slow == fast)
		{
			return true;
		}
	}
	return false;
}

//创建循环链表
list buildCycleList()
{
	list head = buildListTail();
	list curr = head;
	while(curr->next)
		curr = curr->next;
	curr->next = curr;
	list root = curr;
	//头插
// 	for (int i=10;i<20;++i)
// 	{
// 		list node = new Node;
// 		node ->m_data = i;
// 		node -> next = curr->next;
// 		curr->next = node;
// 	}
	//屁股插
	for (int i=10;i<20;++i)
	{
		list node = new Node;
		node ->m_data = i;
		node->next = curr->next;
		curr->next = node;
		curr = node;
	}
	curr= head->next;
	cout<<"创建循环链表:"<<endl;
	while(curr!=root)
	{
		cout<<curr->m_data<<" ";
		curr = curr->next;
	}
	cout<<curr->m_data<<" ";
	curr = curr->next;
	while(curr!=root)
	{
		cout<<curr->m_data<<" ";
		curr = curr->next;
	}
	cout<<endl;
	return head;
}

//循环链表的入口结点
list enterNode(list head)
{
	list fast = head;
	list slow = head;
	list middle ;
	while(fast->next && fast->next->next)
	{
		fast = fast->next->next;
		slow = slow->next;
		if (slow == fast)
		{
			middle = fast;
			break;
		}
	}
	list temp = head;
	while(temp != slow)
	{
		temp = temp->next;
		slow = slow->next;
	}
	cout<<"循环链表的入口结点的数据为:"<<temp->m_data<<endl;
	//cout<<endl;
	return temp;
}

//判断两个单链表是否相交
bool isCross(list head1,list head2)
{
	if (!head1 || !head2)
		return false;
	while(head1->next)
		head1 = head1->next;
	while(head2->next)
		head2 = head2->next;
	if (head2==head1)
		return true;
	else return false;
}

//构造两个相交的单链表
void build2Crosslist(list &head1,list &head2)
{
	head1 = buildListHead();
	list cross = head1->next->next->next;
	head2 = buildListHead();
	list tail = head2;
	while(tail->next)
		tail = tail->next;
	tail->next = cross;
}

//两个相交的链表的首个相交的结点
list firstCrossNode(list head1,list head2)
{
	cout<<"反序遍历两个链表:"<<endl;
	reTraverseList(head1);
	cout<<endl;
	reTraverseList(head2);
	stack<list> stackTemp1;
	stack<list> stackTemp2;
	head1 = head1->next;
	while(head1)
	{
		stackTemp1.push(head1);
		head1 = head1 ->next;
	}
	head2 = head2->next;
	while(head2)
	{
		stackTemp2.push(head2);
		head2 = head2 ->next;
	}
	list cross = stackTemp2.top();
	//list curr = stackTemp2.top();
	while(stackTemp2.top()==stackTemp1.top())
	{
		cross = stackTemp1.top();
		stackTemp1.pop();
		stackTemp2.pop();
	}
	cout<<"相交的第一个结点信息是:"<<cross->m_data<<endl;
	return cross;
}

//两个有序链表的合二为一
list mergeList(list head1,list head2)
{
	if (!head1)
		return head2;
	if(!head2)
		return head1;
	list head = head1;
	list curr = head;
	head1 = head1->next;
	head2 = head2->next;
	while(head1 && head2)
	{
		if (head1->m_data < head2->m_data)
		{
			curr->next = head1;
			head1 = head1->next;
			curr = curr->next;
		}
		else
		{
			curr->next = head2;
			head2 = head2->next;
			curr = curr->next;
		}
	}
	while(head1)
	{
		curr->next = head1;
		head1 = head1->next;
		curr = curr->next;
	}
	while(head2)
	{
		curr->next = head2;
		head2 = head2->next;
		curr = curr->next;
	}
	curr->next = NULL;
	traverseList(head);
	return head;
}

//链表的查找
//链表的倒数第K个元素
list lastKNumber(list head,int k)
{
	int n = k;
	int length = lenthList(head);
	if (k > length)
	{
		return NULL;
	}
	list firs=head->next;
	list second = head->next;
	while(--k)
	{
		firs = firs->next;
	}
	while(firs->next)
	{
		firs = firs->next;
		second = second->next;
	}
	cout<<"倒数第"<<n<<"个元素对应的成员为:"<<second->m_data<<endl;
	return second;
}

//链表的中间那个元素
list middleElement(list head)
{
	list fast = head->next;
	list slow = head->next;
	while(fast->next && fast->next->next)
	{
		fast = fast->next->next;
		slow = slow->next;
	}
	if (!fast->next)
	{
		cout<<"链表的中间元素对应的数据为:"<<slow->m_data<<endl;
		return slow;
	}
	else
	{
		cout<<"链表的中间元素对应的数据为:"<<slow->m_data<<ends<<slow->next->m_data<<endl;
		return slow;
	}
}

//O字型环形链表 约瑟夫环问题
//求环的长度 ---没用上
int lenJoseph(list head)
{
	int len =1;
	list curr = head->next;
	while(curr != head)
	{
		len++;
		curr = curr->next;
	}
	return len;
}

void joseph(list &head,int k)
{
	if (head->next == head)
	{
		return;
	}
	int n =k;
	list pre;
	while(--n)
	{
		pre = head;
		head = head->next;
	}
	
	pre->next = head->next;
	delete head;
	head = NULL;
	head = pre->next;
	joseph(head,k);
}

void joseph(int m,int k)
{
	list head = new Node;
	head->m_data = 1;
	head->next = head;
	list curr = head;
	for (int i=1;i<m;++i)
	{
		list node = new Node;
		node->m_data = i+1;
		node->next = curr->next;
		curr->next = node;
		curr = node;
	}
	//测试
// 	curr = head;
// 	cout<<curr->m_data<<" ";
// 	curr = curr->next;
// 	while(curr!=head)
// 	{
// 		cout<<curr->m_data<<" ";
// 		curr = curr->next;
// 	}
	

	//法一:非递归
// 	list pre;
// 	while(head->next != head)
// 	{
// 		while(--k)
// 		{
// 			pre = head;
// 			head = head->next;
// 		}
// 		k = 3;
// 		pre->next = head->next;
// 		delete head;
// 		head = pre->next;
// 	}
	//法二:
	joseph(head,k);
	cout<<"约瑟夫环最后剩下的元素是:"<<head->m_data<<endl;
}

//链表的逆置操作
list reverseList(list head)
{
	list curr = head->next;
	head->next = NULL;
	while(curr)
	{
		list temp = curr->next;
		curr->next = head->next;
		head->next = curr;
		curr = temp;
	}
	return head;
}

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值