溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

線性表--單鏈表(C++)

發(fā)布時(shí)間:2020-06-28 03:12:41 來(lái)源:網(wǎng)絡(luò) 閱讀:405 作者:nna_0914 欄目:編程語(yǔ)言

單鏈表演示圖:

         

  線性表--單鏈表(C++)

單鏈表結(jié)構(gòu)體:

struct Node
{
	Node(const DataType& d)//節(jié)點(diǎn)的構(gòu)造函數(shù)
	:_data(d)
	,_next(NULL)
	{}
	DataType _data;        //數(shù)據(jù)  
	struct Node *_next;    //指向下一個(gè)節(jié)點(diǎn)的指針
};

帶頭結(jié)點(diǎn)和尾節(jié)點(diǎn)的單鏈表:


線性表--單鏈表(C++)

多一個(gè)Tail指針的好處就是很方便可以找到鏈表尾部,方便在尾部插入一個(gè)元素什么的。


下面我們用類來(lái)實(shí)現(xiàn)單鏈表:

class SList
{
	friend ostream& operator<<(ostream& os, const SList& s);  //輸出運(yùn)算符重載(友元)
public:
	SList()                           //構(gòu)造函數(shù)
		:_head(NULL)
		,_tail(NULL)
	{}
	SList(const SList& s)             //拷貝構(gòu)造
		:_head(NULL)
		, _tail(NULL)
	{
		Node *cur = _head;
		while (cur)
		{
			PushBack(cur->_data );
			cur = cur->_next;
		}
		_tail = cur;
	}
	~SList()                           //析構(gòu)函數(shù)
	{
		if (_head == NULL)
			return;
		Node *cur = _head;
		if (cur != NULL)
		{
			Node *del = cur;
			cur = cur->_next;
			delete del;
		}
		_tail = NULL;
		_head = NULL;
	}

	SList& operator=(SList s)           //賦值運(yùn)算符重載
	{
		swap(_head, s._head);
		swap(_tail, s._tail);
		return *this;
	}


單鏈表最基本的四個(gè)函數(shù):

void SList::PushBack(const DataType& d)   //尾插
{
	Node *newNode = new Node(d);      //構(gòu)建一個(gè)新的節(jié)點(diǎn)
	if (_head == NULL)
	{
		_head = newNode;
		_tail = newNode;
	}
	else
	{
		_tail->_next = newNode;
		_tail = newNode;
	}
}
void SList::PushFront(const DataType& d)   //頭插
{
	Node *newNode = new Node(d);
	if (_head == NULL)
	{
		_head = newNode;
		_tail = newNode;
	}
	else
	{
		newNode->_next = _head;
		_head = newNode;
	}
}
void SList::PopBack()                     //尾刪
{
	if (_head == NULL)
		return;
	else if (_head == _tail)
	{
		delete _tail;
		_tail = NULL;
		_head = NULL;
	}
	else
	{
		Node *cur = _head;
		while (cur->_next != _tail)
		{
			cur = cur->_next;
		}
		delete _tail;
		_tail = cur;
		_tail->_next = NULL;
	}
}
void SList::PopFront()                  //頭刪
{
	if (_head == NULL)
		return;
	else if (_head == _tail)
	{
		delete _tail;
		_tail = NULL;
		_head = NULL;
	}
	else
	{
		Node *del = _head;
		_head = _head->_next;
		delete del;
	}
}


給一個(gè)數(shù)據(jù),若找到該節(jié)點(diǎn)則返回該節(jié)點(diǎn),沒(méi)找到則返回NULL

Node* SList::Find(const DataType& d)
{
	Node *cur = _head;
	while (cur != NULL)
	{
		if (cur->_data == d)
			return cur;
		cur = cur->_next;
	}
	return NULL;
}

給定一個(gè)節(jié)點(diǎn),在該節(jié)點(diǎn)后插入一個(gè)新的節(jié)點(diǎn)

void SList::Insert(Node* pos, const DataType& d)
{
	Node *newNode = new Node(d);
	if (pos == _tail)                    //若給定的節(jié)點(diǎn)是尾節(jié)點(diǎn),此處可以直接調(diào)用尾插
	{
		_tail->_next = newNode;
		_tail = newNode;
	}
	else
	{
		newNode->_next = pos->_next;
		pos->_next = newNode;
	}
}

鏈表的逆序:此處用三個(gè)指針來(lái)實(shí)現(xiàn)

void SList::Reverse()
{
	Node *p1 = NULL;
	Node *p2 = _head;
	Node *newhead = NULL;
	while (p2)
	{
		p1 = p2;
		p2 = p2->_next;
		p1->_next = newhead;
		newhead = p1;
		
	}
	_head = newhead;
}

鏈表的排序:采用冒泡排序

void SList::Sort()
{
	Node *cur = _head;
	Node *end = NULL;
	while (cur != end)
	{
		while (cur->_next  != end)
		{
			if (cur->_data > cur->_next->_data)
			{
				DataType tmp = cur->_data;
				cur->_data = cur->_next->_data;
				cur->_next->_data = tmp;
			}
          cur = cur->_next;
		}
	  end = cur;
      cur = _head;
	}
}

刪除某個(gè)節(jié)點(diǎn)(給定一個(gè)數(shù)據(jù),刪除數(shù)據(jù)與之相等的第一個(gè)節(jié)點(diǎn))

void SList::Remove(const DataType& d)
{
	Node *cur = _head;
	while (cur != NULL)
	{
		if (cur->_data == d)
		{
			Node *del = cur->_next;
			DataType tmp = cur->_data;
			cur->_data = cur->_next->_data;
			cur->_next->_data = tmp;
			cur->_next = cur->_next->_next;
			delete del;
			return;
		}
		cur = cur->_next;
	}
}

刪除某些節(jié)點(diǎn)(給定一個(gè)數(shù)據(jù),刪除數(shù)據(jù)與之相等的每一個(gè)節(jié)點(diǎn))

void SList::RemoveAll(const DataType& d)
{
	Node *cur = _head;
	while (cur != NULL)
	{
		if (cur->_data == d)
		{
			Node *del = cur->_next;
			DataType tmp = cur->_data;
			cur->_data = cur->_next->_data;
			cur->_next->_data = tmp;
			cur->_next = cur->_next->_next;
			delete del;
		}
		cur = cur->_next;
	}
	return;
}

刪除非尾節(jié)點(diǎn)

void SList::EarseNotTail(Node *pos)
{
	Node *del = pos;
	Node *cur = _head;
	while (cur->_next!=pos)     //找到該節(jié)點(diǎn)的前一個(gè)節(jié)點(diǎn)
	{
		cur = cur->_next;
	}
	cur->_next = pos->_next;     //讓它的_next指向要?jiǎng)h除節(jié)點(diǎn)的_next
	delete del;
}

找到中間節(jié)點(diǎn)

Node*  SList::FindMinNode()                //快慢指針問(wèn)題
{                                          //兩個(gè)指針都指向頭結(jié)點(diǎn)
	Node *cur = _head;                 //快的一次走兩步,慢的一次走一步
	Node *fast = cur;                  //當(dāng)快指針走到尾的時(shí)候,慢指針指向中間節(jié)點(diǎn)
	Node *slow = cur;
	while (fast)
	{
		fast = fast->_next->_next;
		slow = slow->_next;
	}
	return slow;
}

刪除倒數(shù)第K個(gè)節(jié)點(diǎn)

void  SList::DelKNode(int k)
{
	Node *cur = _head;
	int i = k - 1;
	while (i)                   //先讓cur指向正數(shù)第K個(gè)節(jié)點(diǎn)
	{
		cur = cur->_next;
		i = i - 1;;
	}
	Node *p1 = _head;            
	Node *tmp = NULL;
	while (cur->_next )          //讓一個(gè)指向頭結(jié)點(diǎn)的指針和cur一起走
	{
		tmp = p1;
		p1 = p1->_next;
		cur = cur->_next;     //當(dāng)cur指向尾節(jié)點(diǎn)時(shí),那個(gè)指針指向倒第K個(gè)節(jié)點(diǎn)
	}
	Node *del = p1;
	tmp->_next = p1->_next ;
	delete p1;

}

檢測(cè)是否帶環(huán)

//檢測(cè)是否帶環(huán)
int  SList::CheckCycle(const SList& s)      //快慢指針問(wèn)題
{
	Node *fast = _head;
	Node *slow = _head;
	while (slow)
	{
		if (slow == fast)
		{
			return 1;
		}
		fast = fast->_next->_next;
		slow = slow->_next;
	}
	return 0;
}

獲取環(huán)的入口點(diǎn)

Node*  SList::GetCycleEoryNode()
{
	Node *cur = _head;
	while (cur)
	{
		if (cur == _tail)
		{
			return cur;
		}
		cur = cur->_next;
	}
	return NULL;
}

判斷是否相交

int  SList::CheckCross(SList& l1, SList& l2)
{
	int count1 = l1.LengthOfList(l1);
	int count2 = l2.LengthOfList(l2);
	if (count1 > count2)
	{
		Node *cur = l1._head;
		while (cur)
		{
			if (l2._tail == cur)
				return 1;
			cur = cur->_next;
		}
	}
	else
	{
		Node *cur = l2._head;
		while (cur)
		{
			if (l1._tail == cur)
				return 1;
			cur = cur->_next;
		}
	}
	return 0;
}

合并兩個(gè)鏈表

int  SList::CheckCross(SList& l1, SList& l2)
{
	int count1 = l1.LengthOfList(l1);
	int count2 = l2.LengthOfList(l2);
	if (count1 > count2)
	{
		Node *cur = l1._head;
		while (cur)
		{
			if (l2._tail == cur)
				return 1;
			cur = cur->_next;
		}
	}
	else
	{
		Node *cur = l2._head;
		while (cur)
		{
			if (l1._tail == cur)
				return 1;
			cur = cur->_next;
		}
	}
	return 0;
}


求兩個(gè)鏈表的交點(diǎn)

Node*  SList::GetLinkCross(SList& l1, SList& l2)
{ 
	int count1 = l1.LengthOfList(l1);
	int count2 = l2.LengthOfList(l2);
	Node *cur1 = l1._head;
	Node *cur2 = l2._head;
	if (count1 > count2)
	{
		Node *cur1 = l1._head;
		Node *cur2 = l2._head;
		while (cur2)
		{
			if (cur2->_next  == cur1->_next )
				return cur1;
			else
			{
				cur1 = cur1->_next;
				cur2 = cur2->_next;
			}
		}
	}
	else
	{
		Node *cur1 = l1._head;
		Node *cur2 = l2._head;
		while (cur1)
		{
			if (cur2->_next == cur1->_next)
				return cur1;
			else
			{
				cur1 = cur1->_next;
				cur2 = cur2->_next;
			}
		}
	}
	return NULL;
}

求鏈表長(zhǎng)度

int SList::LengthOfList(const SList& s)

{

int length = 0;

Node *cur = _head;

while (cur)

{

length++;

cur = cur->_next;

}

return length;

}

以后會(huì)有改進(jìn)版奉上,希望大家多多支持線性表--單鏈表(C++)

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI