C++數據結構與算法(單向鏈表)

目錄

1創建鏈表

1.1創建鏈表的順序結構寫法

1.2利用循環語句創建鏈表(頭插法)

1.3利用循環語句創建鏈表(尾插法)

2刪除節點

3增加節點

4查找節點

4.1鏈表查找元素的節點數或者按照節點查找數據域

4.2查找鏈表中的最值

5修改節點

6鏈表逆置

7刪除鏈表中的最值

8鏈表排序

9鏈表合併

9.1將兩個不同排序的鏈表進行升序排列

9.2將兩個相同排序的鏈表進行升序排列

10測量一個鏈表的長度


鏈表的引出:

       數組是程序設計語言所提供的一種非常有用的數據結構,但是,數組有兩個侷限:1)編譯期就要知道大小;2)數組中的數據在計算機內存中以等間隔分開,這就意味着如果向其中插入一個元素,那麼需要移動該數組中的其他元素。鏈表就不存在這些問題。鏈表是節點的集合。節點中存儲着數據並且會鏈接到其他節點。

       鏈表包含兩個部分:數據域和鏈接域。

單向鏈表

       如果一個節點將指向另一個節點的指針作爲數據成員,那麼多個這樣的節點就可以鏈接起來,只用一個變量能夠訪問整個節點序列。這樣的節點序列就是最常用的鏈表實現方法。鏈表是一種節點組成的數據結構,每個節點都包含某些信息以及指向鏈表另一個節點的指針。如果序列中的節點只包含指向後繼節點的鏈接,該鏈表稱爲單向鏈表

1創建鏈表

1.1創建鏈表的順序結構寫法

#include<iostream>
using namespace std;

class Node  //節點
{
	friend class List; //聲明爲友元類,以使得List的成員函數可以使用Node的私有屬性
private:
	int data;   //節點中的數據
	Node* next; //指針指向下一個節點的指針
};

class List  //鏈表
{
public:
	void test();
	void show();
private:
	Node* first;  //指向第一個節點的指針
};
void List::show()
{
	cout << first->data << endl
		<< first->next->data << endl
		<< first->next->next->data << endl;
}

void List::test()
{
	Node *f = new Node();
	f->data = 44;
	f->next = NULL;

	first = f;

	f = new Node();
	f->data = 72;
	f->next = NULL;

	first->next = f;

	f = new Node();
	f->data = 210;
	f->next = NULL;

	first->next->next = f;
}

int main()
{
	List a;
	a.test();  //創建3個節點
	a.show();   //輸出節點的數據域
	cout << "OK" << endl;
	system("pause");
	return 0;
}

1.2利用循環語句創建鏈表(頭插法

算法思想:從一個空表開始,每次讀入數據,生成新節點,將讀入數據存放到新節點的數據域中,然後將新節點插入到當前鏈表的表頭節點之後,直至讀入結束標誌爲止。

#include<iostream>
#include<iomanip>
using namespace std;

typedef struct node{
	int data;
	struct node *next;
}ElemSN;

//創建鏈表函數 
ElemSN *CreatLink(int a[], int n)
{
	ElemSN *h, *p, *t;  //h表示頭指針,t表示尾指針,p是中間指針 
	int i;
	h = t = (ElemSN *)malloc(sizeof(ElemSN));
	h->data = a[0];
	h->next = NULL;
	for (i = 1; i<n; i++)
	{
		p = (ElemSN *)malloc(sizeof(ElemSN));
		p->data = a[i];
		p->next = NULL;
		t->next = p;
		t = p;
	}
	return h;
}

//輸出函數 
void PrintLink(ElemSN *h)
{
	ElemSN *p;
	for (p = h; p; p = p->next)
		cout << setw(5) << p->data << endl;
}

//主函數 
int main(void)
{
	int a[8] = { 10, 20, 30, 40, 50, 60, 70, 80 };
	ElemSN *head;
	head = CreatLink(a, 8);
	PrintLink(head);
	system("pause");
	return 0;
}

1.3利用循環語句創建鏈表(尾插法

該方法將新節點插到當前單鏈表的表尾上,相對於頭插法的優勢在於少聲明一箇中間指針變量,建議使用尾插法:

//利用結構體(尾插法)創建鏈表
#include<iostream>
#include<iomanip>
using namespace std;

typedef struct node{
	int data;
	struct node *next;
}ElemSN;

//創建鏈表函數(尾插法) 
ElemSN *CreateLink(int a[], int n)
{
	ElemSN *h, *p;
	int i;
	h = NULL;
	for (i = n - 1; i >= 0; i--)
	{
		p = (ElemSN *)malloc(sizeof(ElemSN));
		p->data = a[i];
		p->next = h;
		h = p;
	}
	return h;
}

//輸出函數 
void PrintLink(ElemSN *h)
{
	ElemSN *p;
	for (p = h; p; p = p->next)
		cout << setw(5) << p->data << endl;
}

//主函數 
int main(void)
{
	int a[8] = { 10, 20, 30, 40, 50, 60, 70, 80 };
	ElemSN *head;
	head = CreateLink(a, 8);
	PrintLink(head);
	system("pause");
	return 0;
}

2刪除節點

鏈表刪除節點(三種寫法)

#include<iostream>
#include<iomanip>
using namespace std;

typedef struct node{
	int data;
	struct node *next;
}ElemSN;

ElemSN *CreateLink(int a[], int n)
{
	ElemSN *h, *p;
	int i;
	h = NULL;
	for (i = n - 1; i >= 0; i--)
	{
		p = (ElemSN *)malloc(sizeof(ElemSN));
		p->data = a[i];
		p->next = h;
		h = p;
	}
	return h;
}

void PrintLink(ElemSN *h)
{
	ElemSN *q;
	for (q = h; q; q = q->next)
		cout << setw(5) << q->data;
}

ElemSN *DelkeyNode(ElemSN *h, int key)   //刪除節點
{
	ElemSN *p, *q = NULL;
	p = h;
	while (p)  //從頭指針開始遍歷
	{
		if (p->data != key) //不是待刪節點
		{
			q = p;
			p = p->next;
		}
		else if (p == h)  //是待刪節點,且待刪節點是第一個節點
		{
			h = h->next;  //頭結點後移
			free(p);      //刪除頭節點
			p = h;        //p指向新的頭節點
		}
		else             //是待刪節點,但不是第一個節點
		{
			q->next = p->next;
			free(p);
			p = q->next;
		}
	}
	return h;
}

int main()
{
	int a[8] = { 10, 20, 30, 20, 20, 60, 7, 20 };
	int key;
	ElemSN *head;
	//創建鏈表
	head = CreateLink(a, 8);
	//輸出鏈表
	PrintLink(head);
	cout << endl;
	cout << "請輸入key值: ";
	cin >> key;
	//刪除數據域爲key的值
	head = DelkeyNode(head, key);
	PrintLink(head);
	cout << endl;
	system("pause");
	return 0;
}
#include<iostream>
#include<iomanip>
using namespace std;

typedef struct node{
	int data;
	struct node *next;
}ElemSN;

ElemSN *CreateLink(int a[], int n)
{
	ElemSN *h, *p;
	int i;
	h = NULL;
	for (i = n - 1; i >= 0; i--)
	{
		p = (ElemSN *)malloc(sizeof(ElemSN));
		p->data = a[i];
		p->next = h;
		h = p;
	}
	return h;
}

void PrintLink(ElemSN *h)
{
	ElemSN *q;
	for (q = h; q; q = q->next)
		cout << setw(5) << q->data;
}

ElemSN *DelkeyNode(ElemSN *h, int key)  //刪除節點
{
	ElemSN *p, *q;
	for (p = h; p&&p->data == key; p = p->next);
	h = p;
	if (h->next)
	{
		for (q = h, p = h->next; p; p = p->next)
		{
			if (p->data != key)
			{
				q->next = p;
				q = p;
			}
			else if (!p->next)
			{
				q->next = NULL;
			}
		}
	}
	return h;
}

int main(void)
{
	int a[8] = { 10, 20, 30, 40, 20, 60, 7, 20 };
	int key;
	ElemSN *head;
	//創建鏈表
	head = CreateLink(a, 8);
	//輸出鏈表
	PrintLink(head);
	cout << endl;
	cout<<"請輸入key值: ";
	cin >> key;
	//刪除數據域爲key的值
	head = DelkeyNode(head, key);
	PrintLink(head);
	cout << endl;
	system("pause");
	return 0;
}
#include<iostream>
#include<iomanip>
using namespace std;

typedef struct node{
	int data;
	struct node *next;
}ElemSN;

ElemSN *CreateLink(int a[], int n)
{
	ElemSN *h, *p;
	int i;
	h = NULL;
	for (i = n - 1; i >= 0; i--)
	{
		p = (ElemSN *)malloc(sizeof(ElemSN));
		p->data = a[i];
		p->next = h;
		h = p;
	}
	return h;
}

void PrintLink(ElemSN *h)
{
	ElemSN *q;
	for (q = h; q; q = q->next)
		cout << setw(5) << q->data;
}

ElemSN *DelkeyNode(ElemSN *h, int key)   //刪除節點
{
	ElemSN *p, *t, *h1;
	h1 = NULL;
	t = NULL;
	while (h)
	{
		p = h;  //p指向頭指針
		h = h->next; //頭指針後移
		if (p->data == key) //是待刪節點
			free(p);       //刪除
		else               //不是待刪節點
		{
			p->next = NULL;
			if (!h1)
				h1 = t = p;
			else               
				t = t->next = p;
		}
	}
	return h1;
}


int main()
{
	int a[8] = { 10, 20, 30, 20, 20, 60, 7, 20 };
	int key;
	ElemSN *head;
	//創建鏈表
	head = CreateLink(a, 8);
	//輸出鏈表
	PrintLink(head);
	cout << endl;
	cout << "請輸入key值: ";
	cin >> key;
	//刪除數據域爲key的值
	head = DelkeyNode(head, key);
	PrintLink(head);
	cout << endl;
	system("pause");
	return 0;
}

3增加節點

向鏈表中添加節點(頭插、尾插和任意插)

//向鏈表中添加數據
#include<iostream>
#include<iomanip>
using namespace std;

typedef struct node{
	int data;
	struct node *next;
}ElemSN;

//創建鏈表函數(尾插法) 
ElemSN *CreateLink(int a[], int n)
{
	ElemSN *h, *p;
	int i;
	h = NULL;
	for (i = n - 1; i >= 0; i--)
	{
		p = (ElemSN *)malloc(sizeof(ElemSN));
		p->data = a[i];
		p->next = h;
		h = p;
	}
	return h;
}

//輸出函數 
void PrintLink(ElemSN *h)
{
	ElemSN *p;
	for (p = h; p; p = p->next)
		cout << setw(5) << p->data << endl;
}

//向頭部添加數據
ElemSN * add(int number, ElemSN *head)
{
	ElemSN * temp = (ElemSN *)malloc(sizeof(ElemSN));
	temp->data = number;
	temp->next = NULL;
	ElemSN * p = head;
	head = temp;
	head->next = p;
	return head;
}

//向尾部添加數據
ElemSN * add2(int number, ElemSN *head)
{
	ElemSN * temp = (ElemSN *)malloc(sizeof(ElemSN));
	ElemSN * q = (ElemSN *)malloc(sizeof(ElemSN));
	temp->data = number;
	temp->next = NULL;
	ElemSN * p;
	for (p = head,q->next = p; p; p = p->next,q=q->next);
	q->next = temp;
	return head;
}

//返回鏈表長度
int GetLength(ElemSN *head)
{
	int length = 0;
	ElemSN *p = head;
	while (p != NULL)
	{
		++length;
		p = p->next;
	}
	return length;
}

//從指定位置後面插入元素
ElemSN * IndexInsertNode(ElemSN *head, int num, int pos)
{
	ElemSN *p = head;
	int count = 0;
	int length = GetLength(head);
	cout << "---------------" << endl;
	cout << length << endl;
	if (pos < 0 || pos > length)
		cout << "插入位置不正確!" << endl;
	if (!pos)
	{
		node *temp = new node;
		temp->data = num;
		temp->next = NULL;
		head = temp;
		head->next = p;
		return head;
	}
	while (p != NULL)
	{
		count++;
		if (count == pos)
		{
			node *p1 = new node;
			p1->data = num;
			p1->next = p->next;
			p->next = p1;
		}
		p = p->next;
	}
	return head;
}


//主函數 
int main(void)
{
	int a[8] = { 10, 20, 30, 40, 50, 60, 70, 80 };
	ElemSN *head;
	head = CreateLink(a, 8);
	cout << "原鏈表:" << endl;
	PrintLink(head);
	int number;
	cout << "請輸入要插入的數據:" << endl;
	cin >> number;
	//向鏈表頭部添加數據 head = add(number, head);
	//向鏈表尾部添加數據 head = add2(number, head);
	//指定位置插入數據
	int pos;
	cout << "請輸入要插入的位置:" << endl;
	cin >> pos;
	head = IndexInsertNode(head, number, pos);
	cout << "插入數據後的鏈表:" << endl;
	PrintLink(head);

	system("pause");
	return 0;
}

4查找節點

4.1鏈表查找元素的節點數或者按照節點查找數據域

//在鏈表中查找數據
#include<iostream>
#include<iomanip>
using namespace std;

typedef struct node{
	int data;
	struct node *next;
}ElemSN;

//創建鏈表函數(尾插法) 
ElemSN *CreateLink(int a[], int n)
{
	ElemSN *h, *p;
	int i;
	h = NULL;
	for (i = n - 1; i >= 0; i--)
	{
		p = (ElemSN *)malloc(sizeof(ElemSN));
		p->data = a[i];
		p->next = h;
		h = p;
	}
	return h;
}

//輸出函數 
void PrintLink(ElemSN *h)
{
	ElemSN *p;
	for (p = h; p; p = p->next)
		cout << setw(5) << p->data << endl;
}

int Search_Elem(int num, ElemSN *head)
{
	node *p = new node;
	p = head;
	int index = 1;
	while (p)
	{
		if (num == p->data)
			return index;
		else
		{
			p = p->next;
			++index;
		}
	}
	return -1;
}

int Search_index(int index, ElemSN *head)
{
	node *p = new node;
	int i = 1;
	for (i = 1, p = head; p&&i < index; p = p->next,i++);
	return p->data;
}


//主函數 
int main(void)
{
	int a[8] = { 10, 20, 30, 40, 50, 60, 70, 80 };
	ElemSN *head;
	head = CreateLink(a, 8);
	cout << "原鏈表:" << endl;
	PrintLink(head);
	//int number;
	//cout << "請輸入要查找的數據:" << endl;
	//cin >> number;
	//int index = Search_Elem(number, head);
	//if (index < 0)
	//	cout << "沒找到" << number << endl;
	//else
	//	cout << "找到了" << number << ",它是第" << index << "個節點" << endl;

	int index;
	cout << "查找第幾個節點?" << endl;
	cin >> index;
	int data = Search_index(index, head);
	cout << "第" << index << "個節點的數據是:" << data << endl;

	system("pause");
	return 0;
}

4.2查找鏈表中的最值

/*查找鏈表中的最值*/
#include<iostream>
#include<iomanip>
using namespace std;

typedef struct node{
	int data;
	struct node *next;
}ElemSN;

ElemSN *CreateLink(int a[], int n)
{
	ElemSN *h, *p, *t;
	int i;
	h = t = (ElemSN *)malloc(sizeof(ElemSN));
	h->next = NULL;
	for (i = 0; i<n; i++)
	{
		p = (ElemSN *)malloc(sizeof(ElemSN));
		p->data = a[i];
		p->next = NULL;
		t = t->next = p;
	}
	return h;
}

void PrintLink(ElemSN *h)
{
	ElemSN *p;
	for (p = h; p->next; p = p->next)
		cout << setw(5) << p->next->data;
	cout << endl;
}

int SearchNode_MAX(ElemSN *h)
{
	ElemSN *p;
	int max;
	p = h->next;
	max = h->next->data;
	for (p; p->next; p = p->next)
	{
		if (p->next->data>max)
		{
			max = p->next->data;
			p = p->next;
		}
	}
	return max;
}

int SearchNode_MIN(ElemSN *h)
{
	ElemSN *p;
	int min;
	p = h->next;
	min = h->next->data;
	for (p; p->next; p = p->next)
	{
		if (p->next->data<min)
		{
			min = p->next->data;
			p = p->next;
		}
	}
	return min;
}


int main(void)
{
	int a[8] = { 60, 20, 10, 40, 10, 60, 60, 10 };
	int max, min;
	ElemSN *head;
	//創建帶表頭結點的單向鏈表
	head = CreateLink(a, 8);
	//輸出單向鏈表
	PrintLink(head);
	//找最大值結點
	max = SearchNode_MAX(head);
	cout << "最大值結點的數據域值爲: " << max << endl;
	//找最小值結點
	min = SearchNode_MIN(head);
	cout << "最小值結點的數據域值爲: " << min << endl;
	system("pause");
	return 0;
}

5修改節點

修改鏈表中節點的數據域數據

//在鏈表中修改第index個節點的數據域數據
#include<iostream>
#include<iomanip>
using namespace std;

typedef struct node{
	int data;
	struct node *next;
}ElemSN;

//創建鏈表函數(尾插法) 
ElemSN *CreateLink(int a[], int n)
{
	ElemSN *h, *p;
	int i;
	h = NULL;
	for (i = n - 1; i >= 0; i--)
	{
		p = (ElemSN *)malloc(sizeof(ElemSN));
		p->data = a[i];
		p->next = h;
		h = p;
	}
	return h;
}

//輸出函數 
void PrintLink(ElemSN *h)
{
	ElemSN *p;
	for (p = h; p; p = p->next)
		cout << setw(5) << p->data;
	cout << endl;
}

ElemSN * Modify_index(int index, int num, ElemSN *head)
{
	node *p = new node;
	int i = 1;
	for (i = 1, p = head; p&&i < index; p = p->next, i++);
	p->data = num;
	return head;
}


//主函數 
int main(void)
{
	int a[8] = { 10, 20, 30, 40, 50, 60, 70, 80 };
	ElemSN *head;
	head = CreateLink(a, 8);
	cout << "原鏈表:" << endl;
	PrintLink(head);

	int index;
	cout << "修改第幾個節點?" << endl;
	cin >> index;
	int num;
	cout << "請輸入要修改的值:" << endl;
	cin >> num;
	head = Modify_index(index, num, head);
	cout << "修改後的鏈表是:"<< endl;
	PrintLink(head);

	system("pause");
	return 0;
}

6鏈表逆置

#include<iostream>
#include<iomanip>
using namespace std;

typedef struct node{
	int data;
	struct node *next;
}ElemSN;

//頭插法 
ElemSN *CreateLink1(int a[], int n)
{
	ElemSN *h, *p, *t;
	int i;
	h = t = new node;
	h->next = NULL;
	for (i = 0; i<n; i++)
	{
		p = new node;
		p->data = a[i];
		p->next = NULL;
		t = t->next = p;
	}
	return h;
}

//尾插法
ElemSN *CreateLink2(int a[], int n)
{
	ElemSN *h, *p;
	int i;
	h = NULL;
	for (i = n - 1; i >= 0; i--)
	{
		p = new node;
		p->data = a[i];
		p->next = h;
		h = p;
	}
	return h;
}

void PrintLink(ElemSN *h)
{
	ElemSN *p;
	for (p = h; p->next; p = p->next)
		cout << setw(5) << p->next->data << " ";
}

void NiZhiLink(ElemSN *h)
{
	ElemSN *p, *s;
	p = h->next;
	h->next = NULL;
	while (p)
	{
		s = p->next;
		p->next = h->next;
		h->next = p;
		p = s;
	}
}



int main()
{
	int a[8] = { 10, 20, 30, 40, 50, 60, 70, 80 };
	int key;
	ElemSN *head;
	//創建帶表頭結點的單向鏈表
	head = CreateLink1(a, 8);
	//輸出單向鏈表
	cout << "原鏈表:" << endl;
	PrintLink(head);
	cout << endl;
	NiZhiLink(head);
	cout << "逆置後:" << endl;
	PrintLink(head);
	cout << endl;
	system("pause");
	return 0;
}

7刪除鏈表中的最值

/*查找鏈表中的最值*/
#include<iostream>
#include<iomanip>
using namespace std;

typedef struct node{
	int data;
	struct node *next;
}ElemSN;

ElemSN *CreateLink(int a[], int n)
{
	ElemSN *h, *p, *t;
	int i;
	h = t = (ElemSN *)malloc(sizeof(ElemSN));
	h->next = NULL;
	for (i = 0; i<n; i++)
	{
		p = (ElemSN *)malloc(sizeof(ElemSN));
		p->data = a[i];
		p->next = NULL;
		t = t->next = p;
	}
	return h;
}

void PrintLink(ElemSN *h)
{
	ElemSN *p;
	for (p = h; p->next; p = p->next)
		cout << setw(5) << p->next->data << " ";
	cout << endl;
}

int SearchNode_MAX(ElemSN *h)
{
	ElemSN *p;
	int max;
	p = h->next;
	max = h->next->data;
	for (p; p->next; p = p->next)
	{
		if (p->next->data>max)
		{
			max = p->next->data;
			p = p->next;
		}
	}
	return max;
}

int SearchNode_MIN(ElemSN *h)
{
	ElemSN *p;
	int min;
	p = h->next;
	min = h->next->data;
	for (p; p->next; p = p->next)
	{
		if (p->next->data<min)
		{
			min = p->next->data;
			p = p->next;
		}
	}
	return min;
}

void DelNode(ElemSN *h, int key)
{
	ElemSN *p, *delp;
	p = h;
	while (p->next)
	{
		if (p->next->data - key)
			p = p->next;
		else
		{
			delp = p->next;
			p->next = delp->next;
			free(delp);
		}
	}
}

int main(void)
{
	int a[8] = { 60, 20, 10, 40, 10, 60, 60, 10 };
	int max, min;
	ElemSN *head;
	//創建帶表頭結點的單向鏈表
	head = CreateLink(a, 8);
	//輸出單向鏈表
	PrintLink(head);

	//找最大值結點
	max = SearchNode_MAX(head);
	cout << "最大值結點的數據域值爲:" << max << endl;

	//找最小值結點
	min = SearchNode_MIN(head);
	cout << "最小值結點的數據域值爲:" << min << endl;

	//刪除最大值結點
	DelNode(head, max);
	cout << "刪除最大值結果:";
	PrintLink(head);
	//刪除最小值結點
	DelNode(head, min);
	cout << "刪除最小值結果:";
	PrintLink(head);

	system("pause");
	return 0;
}

8鏈表排序

/*冒泡排序和快速排序*/
#include <iostream>
#include <algorithm>
#include "string.h"
#include "stdio.h"
#include <vector>
#include <deque>
#include<stack>
using namespace std;

struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) : val(x), next(NULL) {}
};
class List{
public:
	ListNode* CreatList(int* arr, int len)
	{
		int val;
		ListNode* pHead = new ListNode(arr[0]);
		ListNode* pCurrent = NULL;
		ListNode* rear = pHead;
		int count = 1;
		while (count<len)
		{
			ListNode* pCurrent = new ListNode(arr[count]);
			rear->next = pCurrent;
			rear = pCurrent;
			count++;
		}
		rear->next = NULL;
		return pHead;
	}
	void ShowList(ListNode* pHead)
	{
		while (pHead)
		{
			cout << pHead->val << " ";
			pHead = pHead->next;
		}
		cout << endl;
	}
	//得到鏈表中最後一個結點
	ListNode* GetLastNode(ListNode* pHead)
	{
		ListNode* pNode = pHead;
		while (pNode->next != NULL)
		{
			pNode = pNode->next;
		}
		return pNode;
	}
};
class Sort{
public:
	//冒泡排序
	ListNode* BubbleSortList(ListNode* pHead)
	{
		ListNode* pNode1 = pHead;
		ListNode* pNode2 = pHead;
		if (pHead == NULL)
			return NULL;
		for (; pNode1->next != NULL; pNode1 = pNode1->next)
		{
			for (pNode2 = pHead; pNode2->next != NULL; pNode2 = pNode2->next)
			{
				if (pNode2->val>pNode2->next->val)
				{
					int temp = pNode2->val;
					pNode2->val = pNode2->next->val;
					pNode2->next->val = temp;
				}
			}
		}
		return pHead;
	}
	//快速排序
	void QuickSortList(ListNode* pHead, ListNode* pEnd)
	{
		if (pHead != pEnd)
		{
			ListNode* part = Partition(pHead, pEnd);
			QuickSortList(pHead, part);
			QuickSortList(part->next, pEnd);

		}
	}
	ListNode* Partition(ListNode* pBegin, ListNode* pEnd)
	{

		int key = pBegin->val;
		ListNode* pSlow = pBegin;
		ListNode* pFast = pSlow->next;
		ListNode* temp = pBegin;

		while (pFast != NULL&&pFast != pEnd->next)
		{
			if (pFast->val <key)
			{
				temp = pSlow;
				pSlow = pSlow->next;

				swap(pSlow->val, pFast->val);
			}

			pFast = pFast->next;
		}
		swap(pSlow->val, pBegin->val);
		return temp;//返回的結點爲支點節點的前一個結點    
	}
};
int main()
{
	int array[] = { 3, 4, 5, 1, 2, 8, 7 };
	List list;
	Sort sort;
	ListNode* pHead1 = list.CreatList(array, sizeof(array) / sizeof(array[0]));
	ListNode* pHead2 = list.CreatList(array, sizeof(array) / sizeof(array[0]));
	list.ShowList(pHead1);
	sort.BubbleSortList(pHead1);
	list.ShowList(pHead1);
	ListNode* pEnd = list.GetLastNode(pHead2);
	//cout<<pEnd->val<<endl;
	sort.QuickSortList(pHead2, pEnd);
	list.ShowList(pHead2);
	system("pause");
	return 0;
}

9鏈表合併

9.1將兩個不同排序的鏈表進行升序排列

算法思想:將不同排序的兩個鏈表進行合併,如果要求合併的鏈表進行降序(升序)排列,那麼需要將升序(降序)的鏈表進行逆置後再進行合併。

/*
* 有兩個鏈表,第一個升序,第二個降序,合併爲一個升序鏈表
*/

#include <iostream>

#define NULL 0

using namespace std;

struct Node {
	char data;
	Node *next;
};

Node *create() {
	Node *head = NULL;
	Node *rear = head;
	Node *p; // The pointer points to the new created node.
	char tmp;

	do {
		cout << "Please input integer or char '#':";  //#是停止標誌
		cin >> tmp;
		if (tmp != '#') {
			p = new Node;
			p->data = tmp;
			p->next = NULL;

			if (head == NULL) {
				head = p;
			}
			else {
				rear->next = p;
			}
			rear = p;
		}
	} while (tmp != '#');

	return head;
}

void print(Node *head) {
	Node *p = head;
	if (head != NULL) {
		do {
			cout << p->data << ' ';
			p = p->next;
		} while (p != NULL);
	}
	cout << endl;
}

/**
* Reverse list.
* @param head The head pointer. Use & here since the function body changed the head pointer.
* @return The reversed list header.
*/
Node *reverse(Node *&head) {
	if (head == NULL) {
		return NULL;
	}

	Node *pre, *cur, *ne;
	pre = head;
	cur = head->next;
	while (cur) {
		ne = cur->next; // Store next pointer.
		cur->next = pre; // Reverse the current code pointer.
		pre = cur;
		cur = ne;
	}

	head->next = NULL;
	head = pre;
	return head;
}

Node *merge(Node *l1, Node *l2) {
	Node *l2Reverse = reverse(l2);
	Node *p = new Node;
	p->next = NULL;
	Node *q = p;
	while (l1 && l2Reverse) {
		if (l1->data < l2Reverse->data) {
			p->next = l1;
			l1 = l1->next;
		}
		else {
			p->next = l2Reverse;
			l2Reverse = l2Reverse->next;
		}
		p = p->next;
	}

	if (l1) {
		p->next = l1;
	}
	else if (l2Reverse) {
		p->next = l2Reverse;
	}

	return q->next;
}

int main() {
	Node *list1 = create();
	cout << "The first list is:";
	print(list1);

	Node *list2 = create();
	cout << "The second list is:";
	print(list2);

	cout << "The merged list is:";
	Node *list = merge(list1, list2);
	print(list);
	system("pause");
	return 0;
}

結果:

9.2將兩個相同排序的鏈表進行升序排列

/*將兩個升序排序的鏈表合併成一個升序鏈*/

#include<iostream>
#include<iomanip>
using namespace std;

//定義結構體單元 
typedef struct node{
	int data;//結構體數據域 
	struct node* next;//結構體指針域 
}ElemSN;
//逆向創建單向鏈表(頭插法)
ElemSN *PreCreatLink(int a[], int n)
{
	ElemSN *head = NULL, *p;
	for (int i = n - 1; i>-1; i--)
	{
		p = (ElemSN*)malloc(sizeof(ElemSN));
		p->data = a[i];
		p->next = head;
		head = p;
	}
	return head;
}


ElemSN* Combine(ElemSN *head1, ElemSN *head2)
{
	ElemSN *head, *p, *tail = NULL;
	head = NULL;
	while (head1&&head2)
	{
		if (head1->data<head2->data)
		{
			p = head1;
			head1 = head1->next;
		}
		else
		{
			p = head2;
			head2 = head2->next;
		}
		p->next = NULL;
		if (!head)
			head = tail = p;
		else
		{
			tail = tail->next = p;
		}
	}
	if (head1)
		p = head1;
	else
		p = head2;
	tail->next = p;
	return head;
}

//打印鏈表所有結點的值
void PrintLink(ElemSN* head)
{
	ElemSN *p = head;
	for (; p; p = p->next)
		cout<<setw(5)<<p->data;
	cout << endl;
}


int main()
{
	ElemSN *head1, *head2, *head;
	int a[7] = { 2, 3, 5, 6, 7, 9, 11 };
	int b[5] = { 2, 4, 5, 7, 9 };
	
	
	head1 = PreCreatLink(a, 7);    //創建鏈表head1 
	head2 = PreCreatLink(b, 5);    //創建鏈表head2 
	cout << "鏈表A:" << endl;
	PrintLink(head1);
	cout << "鏈表B:" << endl;
	PrintLink(head2);

	head = Combine(head1, head2);  //將兩個有序鏈表合併成一個有序鏈表 
	cout << "合併的升序鏈表:" << endl;
	PrintLink(head);       //輸出鏈表 
	system("pause");
	return 0;
}

結果:

10測量一個鏈表的長度

/*測量鏈表長度*/
#include<iostream>
#include<iomanip>
using namespace std;

typedef struct node{
	int data;
	struct node *next;
}ElemSN;

ElemSN *CreateLink(int a[], int n)
{
	ElemSN *h, *p;
	int i;
	h = NULL;
	for (i = n - 1; i >= 0; i--)
	{
		p = (ElemSN *)malloc(sizeof(ElemSN));
		p->data = a[i];
		p->next = h;
		h = p;
	}
	return h;
}

void PrintLink(ElemSN *h)
{
	ElemSN *p;
	for (p = h; p; p = p->next)
		cout<<setw(5)<<p->data;
	cout << endl;
}

ElemSN *DelHeadnode(ElemSN *h)
{
	ElemSN *delp;
	delp = h;
	h = h->next;
	free(delp);
	return h;
}

int ListLength(ElemSN *h)
{
	ElemSN *p;
	int j;
	p = h;
	j = 0;       //用於存放單向鏈表的長度
	while (p != NULL)
	{
		p = p->next;
		j++;
	}
	return j;
}

int main()
{
	int a[8] = { 10, 20, 30, 40, 50, 60, 70, 80 };
	ElemSN *head;
	int length;
	//創建鏈表
	head = CreateLink(a, 8);
	//輸出鏈表
	cout << "單向鏈表爲:" << endl;
	PrintLink(head);
	//測量單向鏈表的長度
	length = ListLength(head);
	cout<<"該單向鏈表的長度爲: "<<length;
	cout << endl;
	system("pause");
	return 0;
}

結果圖:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章