您的位置:首页 > 职场人生

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

2015-09-29 23:33 639 查看
/***************链表各类操作*********************
*** 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
4000
{
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息