c++实现单向单链表及常见面试题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c++实现单向单链表及常见面试题相关的知识,希望对你有一定的参考价值。
1.单链表
链表中的数据是以结点来表示的,每个结点的构成:元素+ 指针,元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。
2、链表的结点结构
│data │next |
data域--存放结点值的数据域
next域--存放结点的直接后继的地址(位置)的指针域
注:链表通过每个结点的链域将线性表的n个结点按其逻辑顺序链接在一起的。
"LSist.h"
#pragma once
#include <iostream>
using namespace std;
typedef int DataType;
struct Node
{
Node(const DataType& d) //初始化Node
:_data(d)
,_next(0)
{ }
DataType _data;//数据域
struct Node* _next;//指针域
};
class SList
{
//因在类外重载"<<",所以应声明为友元
friend ostream& operator<<(ostream& os,const SList& s);
public:
SList() //构造函数
:_head(0)
,_tail(0)
{}
~SList() //析构函数
{
Node* cur = _head;
if(_head == NULL)
return;
while(cur->_next != NULL)
{
Node* del = cur;
cur = cur->_next;
delete del;
}
delete cur;
cur = NULL;
_head = NULL;
_tail = NULL;
}
SList(SList& s) //拷贝构造函数
:_head(0)
,_tail(0)
{
Node* cur = s._head;
while(cur)
{
PushBack(cur->_data);
cur = cur->_next;
}
}
//SList& operator=(SList s)
//{
// swap(_head,s._head);
// swap(_tail,s._tail);
// return *this;
//}
SList& operator=(SList& s) //赋值函数
{
if( this != &s )
{
SList tmp(s);
swap(_head,tmp._head);
swap(_tail,tmp._tail);
}
return *this;
}
public:
void PushBack(const DataType& d);//后插
void PopBack();//后删
void PushFront(const DataType& d);//前插
void PopFront();//前删
Node* Find(const DataType& d);//查找某一个元素
void Insert(Node* pos,const DataType& d);//在某个位置后 插入元素
void Reverse(SList& s);//逆置
void Sort(SList& s);//排序
void Remove(const DataType& d);//删除某一元素
void RemoveAll(const DataType& d);//删除所有d元素
//面试题
void EraseNotTail(Node* pos);//删除非头结点
void InsertFrontNode(Node* pos, const DataType& d);
Node* FindMidNode(SList& s);
void DelKNode(DataType k);//删除第k个结点
void CheckCross(SList& l1,SList& l2);//两链表是否相交
Node* CheckCycle(SList& l1);//判断链表中是否有圈
int GetCircleLength(Node* meet);//圈的长度
Node* GetCycleEntryNode(Node* meetNode);//圈的入口
SList Merge(SList& l1, SList& l2);//将链表合并
private:
Node* _head; //头指针
Node* _tail; //尾指针
};
//函数的实现
//函数在类外实现,所以应加上域名
"LSist.cpp"
#include "SList.h"
ostream& operator<<(ostream& os,const SList& s)
{
Node* cur = s._head;
while(cur)
{
os<<cur->_data<<"->";
cur = cur->_next;
}
os<<"over"<<endl;
return os;
}
void SList::PushBack(const DataType& d)
{
Node* newNode = new Node(d);
if(_head == NULL)
{
_head = newNode;
_tail = _head;
}
else
{
_tail->_next = newNode;
_tail = newNode;
}
}
void SList::PopBack()
{
Node* cur = _head;
if(_head == NULL)
{
return;
}
else if(_head == _tail)
{
delete _head;
_head = NULL;
_tail = NULL;
return;
}
else
{
while(cur->_next != _tail)
{
cur = cur->_next;
}
delete _tail;
_tail = cur;
_tail->_next = NULL;
}
}
void SList::PushFront(const DataType& d)
{
Node* newNode = new Node(d);
if(_head == NULL)
{
_head = newNode;
_tail = _head;
}
else
{
newNode->_next = _head;
_head = newNode;
}
}
void SList::PopFront()
{
if(_head == NULL)
{
return;
}
else if(_head == _tail)
{
delete _head;
_head = NULL;
_tail = NULL;
}
else
{
Node* del = _head;
_head = _head->_next;
delete del;
}
}
Node* SList::Find(const DataType& d)
{
Node* cur = _head;
while(cur)
{
if(cur->_data == d)
{
return cur;
}
cur = cur->_next;
}
return NULL;
}
void SList::Insert(Node* pos,const DataType& d)
{
Node* newNode = new Node(d);
if(pos == _tail)
{
_tail->_next = newNode;
_tail = newNode;
}
else
{
newNode->_next = pos->_next;
pos->_next = newNode;
}
}
void SList::Reverse(SList& s)
{
Node* newNode = NULL;
Node* cur = s._head;
Node* prev = NULL;
if(s._head == NULL)
return;
else if(s._head == s._tail)
return;
else
{
while(cur)
{
prev = cur;
cur = cur->_next;
prev->_next = newNode;
newNode = prev;
}
s._head = newNode;
}
}
void SList::Sort(SList& s)
{
if(s._head == NULL)
{
return;
}
else if(s._head == s._tail)
{
return;
}
else
{
Node* cur = NULL;
Node* prev = NULL;
DataType tmp = 0;
while(s._head != prev)
{
cur = s._head;
while(cur&&(cur->_next != prev))
{
if(cur->_data > cur->_next->_data)
{
tmp = cur->_data;
cur->_data = cur->_next->_data;
cur->_next->_data = tmp;
}
cur = cur->_next;
}
prev = cur;
}
}
}
void SList::Remove(const DataType& d)
{
Node* cur = _head;
Node* prev = _head;
Node* del = NULL;
if(_head == NULL)
return;
while(cur)
{
if(cur->_data == d)
{
del = cur;
if(cur == _head)
{
_head = _head->_next;
cur = _head;
delete del;
return;
}
else
{
prev->_next = cur->_next;
cur = prev->_next;
delete del;
return;
}
}
prev = cur;
cur = cur->_next;
}
}
void SList::RemoveAll(const DataType& d)
{
Node* cur = _head;
Node* prev = _head;
Node* del = NULL;
if(_head == NULL)
return;
while(cur)
{
if(cur->_data == d)
{
del = cur;
if(cur == _head)
{
_head = _head->_next;
cur = _head;
}
else
{
prev->_next = cur->_next;
cur = prev->_next;
}
delete del;
}
else
{
prev = cur;
cur = cur->_next;
}
}
}
void SList::EraseNotTail(Node* pos)
{
DataType tmp = 0;
Node* del = NULL;
tmp = pos->_data;
pos->_data = pos->_next->_data;
pos->_next->_data =tmp;
del = pos->_next;
pos->_next = del->_next;
delete del;
del = NULL;
}
Node* SList::FindMidNode(SList &s)
{
Node* fast = s._head;
Node* slow = s._head;
if(fast == NULL)
return NULL;
while(fast->_next)
{
if(fast->_next->_next != NULL)
{
fast = fast->_next->_next;
slow = slow->_next;
}
else
{
return slow;
}
}
return slow;
}
void SList::InsertFrontNode(Node* pos, const DataType& d)
{
Node* newNode = new Node(d);
Node* cur = _head;
Node* front = cur;
if(pos == _head)
{
newNode->_next = _head;
_head = newNode;
}
else
{
cur = cur->_next;
while(cur)
{
if(cur == pos)
{
newNode->_next = front->_next;
front->_next = newNode;
}
cur = cur->_next;
front = front->_next;
}
}
}
void SList::DelKNode(DataType k)
{
Node* fast = _head;
Node* slow = _head;
Node* del = NULL;
Node* cur = NULL;
if(_head == NULL)
return;
while(--k)
{
fast = fast->_next;
}
while(fast->_next)
{
fast = fast->_next;
cur = slow;
slow = slow->_next;
}
del = slow;
cur->_next = del->_next;
delete del;
del = NULL;
}
void SList::CheckCross(SList &l1, SList &l2)
{
SList l3;
Node* cur1 = l1._head;
Node* cur2 = l2._head;
l1._tail = l3._head;
l2._tail = l3._head;
while(cur1)
{
cur1 = cur1->_next;
}
while(cur2)
{
cur2 = cur2->_next;
}
if(cur1 == cur2)
{
cout<<"链表相交"<<endl;
}
else
{
cout<<"链表不相交"<<endl;
}
}
Node* SList::CheckCycle(SList& l1)
{
Node* fast = l1._head;
Node* slow = l1._head;
while(fast&&fast->_next)
{
fast = fast->_next->_next;
slow = slow->_next;
if(fast == slow)
{
return slow;//相遇的点
}
}
return NULL;
}
int SList::GetCircleLength(Node* meet)
{
Node* start = meet;
int count = 0;
do
{
start = start->_next;
count++;
}while(start != meet);
return count;
}
Node* SList::GetCycleEntryNode(Node* meetNode)
{
Node* entry = _head;
while(entry != meetNode)
{
entry = entry->_next;
meetNode = meetNode->_next;
}
return entry;
}
SList SList::Merge(SList& l1, SList& l2)
{
SList newNode;
Node* cur1;
Node* cur2;
if((l1._head == l2._head)&&(l1._tail == l2._tail))
return l1;
if((l1._head == NULL)&&(l2._head != NULL))
return l2;
if((l1._head != NULL)&&(l2._head == NULL))
return l1;
if(l1._head->_data < l2._head->_data)
{
newNode._head= l1._head;
l1._head = l1._head->_next;
}
else
{
newNode._head = l2._head;
l2._head = l2._head->_next;
}
cur1 = l1._head;
cur2 = l2._head;
Node* prev = newNode._head;
while(cur1&&cur2)
{
if(cur1->_data < cur2->_data)
{
prev->_next = cur1;
cur1 = cur1->_next;
prev = prev->_next;
}
else
{
prev->_next = cur2;
prev = prev->_next;
cur2 = cur2->_next;
}
}
if(cur1)
{
prev->_next = cur1;
}
if(cur2)
{
prev->_next = cur2;
}
return newNode;
}
//函数测试
"test.cpp"
#include "SList.h"
void Test1()
{
SList l1;
/*l1.PushBack(1);
l1.PushBack(2);
l1.PushBack(3);
l1.PushBack(4);
l1.PopBack();*/
l1.PushFront(1);
l1.PushFront(2);
l1.PushFront(3);
l1.PushFront(4);
l1.PopFront();
cout<<l1;
SList l2(l1);
cout<<l2;
SList l3;
l3 = l2;
cout<<l3;
}
void Test2()
{
SList l1;
l1.PushBack(1);
l1.PushBack(2);
l1.PushBack(3);
l1.PushBack(4);
l1.PushBack(5);
l1.PushBack(6);
cout<<l1;
/*if(ret != NULL)
{
cout<<ret->_data<<endl;
}
else
{
cout<<"链表中无此元素"<<endl;
}*/
//l1.Insert(ret,5);
//cout<<l1;
}
void Test3()
{
SList l1;
l1.PushFront(3);
l1.PushFront(2);
l1.PushFront(3);
l1.PushFront(4);
l1.PushFront(3);
l1.PushFront(5);
cout<<l1;
/*l1.Reverse(l1);
cout<<l1;*/
/*l1.Sort(l1);
cout<<l1;*/
l1.Remove(4);
//l1.RemoveAll(3);
cout<<l1;
}
void Test4()
{
SList l1;
l1.PushFront(1);
l1.PushFront(2);
l1.PushFront(3);
l1.PushFront(4);
l1.PushFront(5);
l1.PushFront(6);
l1.PushFront(7);
l1.PushFront(8);
cout<<l1;
/*Node *ret = l1.Find(4);
l1.InsertFrontNode(ret,10);*/
//l1.EraseNotTail(ret);
l1.DelKNode(3);
cout<<l1;
/*Node* ret = l1.FindMidNode(l1);
cout<<ret->_data<<endl;*/
}
void Test5()
{
SList l1;
SList l2;
SList l3;
l1.PushBack(1);
l1.PushBack(2);
l1.PushBack(3);
l1.PushBack(4);
l2.PushFront(5);
l2.PushFront(6);
l2.PushFront(7);
l3.PushBack(8);
l3.PushBack(9);
l3.CheckCross(l1,l2);
}
void Test6()
{
SList l1;
l1.PushBack(1);
l1.PushBack(3);
l1.PushBack(4);
l1.PushBack(6);
cout<<l1;
Node* end = l1.Find(6);
end->_next = l1.Find(3);
Node* meetNode = l1.CheckCycle(l1);
cout<<meetNode->_data<<endl;
//DataType ret = l1.GetCircleLength(meetNode);
//Node* ret = l1.GetCycleEntryNode(meetNode);
//cout<<ret->_data<<endl;
}
void Test7()
{
SList l1;
SList l2;
SList l3;
l1.PushBack(1);
l1.PushBack(3);
l1.PushBack(4);
l1.PushBack(6);
cout<<l1;
l2.PushBack(2);
l2.PushBack(5);
cout<<l2;
l3 = l3.Merge(l1,l2);
cout<<l3;
}
int main()
{
Test6();
return 0;
}
以上是关于c++实现单向单链表及常见面试题的主要内容,如果未能解决你的问题,请参考以下文章