1. 程式人生 > >連結串列常見操作:有序連結串列合併去重

連結串列常見操作:有序連結串列合併去重

兩個升序連結串列合併,並要求去掉重複元素 。

分析:

  1. 如何使連結串列本身是有序的,這個我們可以在加入元素的過程中做到
  2. 合併,並去掉重複元素,這個是難點
思路:主要思想類似於直接插入排序歸併排序
  1. 指標p指向list1,指標q指向list2,由於list1已經有序,我們只需要把q指向的節點插入一個原本有序的表,這不就是直接插入排序演算法嗎?當然,得把p移動到合適位置。
  2. 再由於list2也已經有序,因此插入過程中p不需回溯,只需不斷地往後移動,這不就是歸併排序嗎?如果q指向節點的值域和p指向節點的值域相同,則應該丟掉此節點(去重),q=q->next,就行了。
細節看程式碼:
#include<iostream>
#include<iomanip>
using namespace std;
class Node   //節點類
{
public:
	int value;
	Node *next;
	Node(int value, Node *next=NULL) :value(value), next(next){};  //建構函式
};
class List  //連結串列類  
{
private:
	Node *head;
public:
	List()     //建構函式  
	{
		head = new Node(0, NULL);  //頭節點  
	}
	~List();   //解構函式
	void print();
	void add(int value);
	void merge(List list);
};
void List::add(int value)   //新增元素,升序  
{
	if (head->next == NULL)   //如果表中無元素  
	{
		head->next = new Node(value, NULL);
		return;
	}
	Node *p = head;
	while (p->next && p->next->value<value)
		p = p->next;
	if (p->next == NULL)  //如果到達表的末尾  
	{
		p->next = new Node(value);
		p->next->next = NULL;
	}
	else
	{
		Node *node = new Node(value);
		node->next = p->next;
		p->next = node;
	}
}
void List::merge(List list)   //合併連結串列,思路:把list中的節點用類似於直接插入的方法進行插入
{
	Node*p = head;
	Node*q = list.head->next;
	for (; q; q = q->next)
	{
		while (p->next && p->next->value < q->value)   //為q所指向節點的插入,尋找合適的位置
			p = p->next;
		if (p->next == NULL)   //到末尾
		{
			p->next = new Node(q->value);
			p->next->next = NULL;   //這一句可以不加
			continue;
		}
		if (q->value == p->next->value)   //重複元素不新增
		{
			continue;
		}
		Node *node = new Node(q->value);
		node->next = p->next;
		p->next = node;
	}
}
void List::print()
{
	for (Node* p = head->next; p; p = p->next)
		cout << setw(4) << p->value;
	cout << endl;
}
List::~List()
{
	Node *q, *p = head;
	while (p)
	{
		q = p->next;
		delete p;
		p = q;
	}
}
int main()
{
	// 兩個升序連結串列合併,並要求去掉重複元素  
	List list1;
	list1.add(1);
	list1.add(5);
	list1.add(2);
	list1.add(10);
	list1.add(13);
	list1.add(6);
	cout << "表一" << endl;
	list1.print();   //打印表一  
	List list2;
	list2.add(0);
	list2.add(5);
	list2.add(2);
	list2.add(8);
	list2.add(19);
	list2.add(1);
	list2.add(56);
	cout << "表二" << endl;
	list2.print();
	list1.merge(list2);
	cout << "合併後" << endl;
	list1.print();
	system("pause");
	return 0;
}
執行:
思考:這裡要求去重,我們可以寫一個簡單點的:不去重的,但要求保持有序,大家可以試試。可以寫在評論裡哦,我的的寫在一樓,歡迎不吝賜教,thanks。

若是對你有所幫助,或是覺得有意思,希望頂一個哦。
專欄目錄: