数据结构实验之查找与排序

查找与排序

  • 顺序查找
  • 冒泡排序与折半查找
  • 简单选择排序
  • 直接插入排序
  • 快速排序

顺序查找

一:顺序查找
顺序查找:从表的一端开始,依次将记录的关键字和给定值进行比较,若某个记录的关键字和给定值相等,则查找成功;反之,若扫描整个表后,仍未找到关键字和给定值相等的记录,则查找失败。
顺序查找方法既适用于线性表的顺序存储结构,又适用于线性表的链式存储结构。

  1. 编程实现对包含n(n>9)个元素的链式存储的线性表进行顺序查找,输出查找结果;
    例如线性表((xu1,39), (xu2,90), (xu3,37), (xu4,50), (xu5,35), (xu6,28),(xu7, 6), (xu8, 0), (xu9, 12), (xu10,23), (xu11,78))及待查找记录23,58,输入23,表中存在待查找记录,则显示该记录在表中位置10,输入58显示该记录不存在。

循环遍历比较直至找到需要查找的数据

#include
#include
using namespace std;
typedef struct Xu {
	string key;
	int n;
}Xu;
typedef struct LNode {
	Xu date;
	struct LNode *next;
}LNode,*LinkList;
void InitList(LinkList &L) {
	string a[11] = { "xu1","xu2","xu3","xu4","xu5","xu6","xu7","xu8","xu9","xu10","xu11" };
	int b[11] = { 39,90,37,50,35,28,6,0,12,23,78 };
	L = new LNode;
	L->next = NULL;
	//用r来代替L,是为了不改变头指针
	LNode *r = L;
	for (int i = 0;i < 11;i++) {
		LinkList p = new LNode;
		p->date.key = a[i];
		p->date.n = b[i];
		p->next = NULL;
		r->next = p;
		r = p;
	}
}
void SearchList(LinkList &L,int n) {
	LNode *r = L->next;
	//用falg来确定当前指针的位置
	int flag = 1;
	//指针不为空,就循环遍历
	while (r != NULL) {
		//相等后打印并跳出循环
		if (r->date.n == n) {
			cout << "该记录为:  " << r->date.key << "   " << r->date.n
				<< "   " << "在表中位置为; " << flag << endl;
			break;
		}
		else {
			r = r->next;
			flag++;
		}
	}
	//指针为空,说明循环一遍后没找到需要查找的数据
	if (r == NULL)
		cout << "该记录不存在" << endl;

}
int main() {
	LinkList L;
	InitList(L);
	int n=0;
	cout << "输入您想要查找的数据" << endl;
	cin >> n;
	SearchList(L,n);
	system("pause");
}

数据结构实验之查找与排序_第1张图片

冒泡排序与折半查找

二:冒泡排序与折半查找
冒泡排序:首先将第一个数据和第二个数据进行比较,若为逆序,则交换两个数据。然后比较第二个数据和第三个数据。依次类推,直至第n-1个数据和第n个数据进行过比较为止。上述过程称作第一趟起泡排序,其结果使得最大的数据被安置到最后的位置上。
然后进行第二趟起泡排序,对前n-1 个数据进行同样操作,其结果是使次大的数据被安置到第n-1个位置上。
循环直至排序完成
折半查找:从表的中间记录开始,如果给定值和中间记录的关键字相等,则查找成功;如果给定值大于或者小于中间记录的关键字,则在表中大于或小于中间记录的那一半中查找,这样重复操作,直到查找成功,或者在某一一步中查找区间为空,则代表查找失败。

  1. 置查找区间初值,low为1, hig为表长
  2. 当low小于等于high时,循环执行以下操作:
  3. mid取值为low和high的中间值;
  4. 将给定值key与中间位置记录的关键字进行比较,若相等则查找成功,返回中间位置mid;
  5. 若不相等则利用中间位置记录将表对分成前、后两个子表。如果 key比中间位置记录的关键字小,则high取为mid-1, 否则low取为mid+1
  6. 循环结束,说明查找区间为空,则查找失败,返回0

编程实现对包含n(n>11)个元素的线性表进行冒泡排序,输出排序结果。
例如线性有序表((a, 62),(b, 23),(c, 28),(d, 45),(e, 77),(f, 19),(g, 50),(h, 60),(i, 18),(j, 90), (k,66), (m,43))。
编程实现对上一步生成的有序排列、顺序存储的线性表进行折半查找,输出查找结果;
例如对线性表查找记录28,58,输入28,表中存在待查找记录,则显示该记录在表中位置,输入58显示该记录不存在。

#include
#include
using namespace std;
typedef struct Person {
	string key;
	int n;
}Person;
typedef struct Data {
	Person *P = new Person[50];
	int length=0;
}Data;
void InitData(Data &d) {
	string a[12] = { "a","b","c","d","e","f","g","h","i","j","k" };
	int b[12] = {62,23,28,45,77,19,50,60,18,90,66,43 };
	for (int i = 0;i < 11;i++) {
		d.P[d.length].key = a[i];
		d.P[d.length].n = b[i];
		d.length++;
	}
}
//冒泡排序
void Bubble_Sort(Data &d) {
	for(int i=0;i<d.length-1;i++)
		for (int j = 0;j < d.length-1- i;j++) {
			if (d.P[j].n > d.P[j + 1].n) {
				Person p = d.P[j];
				d.P[j] = d.P[j + 1];
				d.P[j+ 1] = p;
			}
		}
}
void Print(Data &d) {
	for (int i = 0;i <=d.length-1;i++) {
		cout << d.P[i].key << "  " << d.P[i].n << endl;
	}
}
void Search_Bin(Data &d, int n) {
	int low = 0;
	int high = d.length-1;
	int mid = 0;
	int flag = 0;
	int locate = 1;
	while (low <= high) {
		mid = (low + high) / 2;
		if (d.P[mid].n == n)
		{
			flag = 1;
			for (int i = 0;i <= d.length - 1;i++) {
				if (d.P[i].n == n)
					break;
				else
					locate++;
			}
			cout << "该记录为:  " << d.P[mid].key << "   " << d.P[mid].n
				<< "   " << "在表中位置为; " << locate << endl;
			break;
		}
		else if (n < d.P[mid].n)
			high = mid - 1;
		else low = mid + 1;
	}
	if (flag == 0)
		cout << "该记录不存在" << endl;
	

}
int main() {
	Data d;
	InitData(d);
	cout << "冒泡排序后的结果" << endl;
	Bubble_Sort(d);
	Print(d);
	int n = 0;
	cout << "输入您想要查找的数据" << endl;
	cin >> n;
	Search_Bin(d,n);
	system("pause");
}

数据结构实验之查找与排序_第2张图片

简单选择排序

三:简单选择排序
简单选择排序:每一趟从待排序的记录中选出关键字最小的记录,按顺序放在已排序的记录序列的最后,直到全部排完为止。也称作直接选择排序
初始关键字 49 38 65 97 4913 27 76
一趟排序结果(13) 38 65 97 49
49 27 76
二趟排序结果(13 27) 65 97 49* 49 38 76
三趟排序结果(13 27 38) 97 49* 49 65 76
四趟排序结果(13 27 38 49*) 97 49 65 76
五趟排序结果(13 27 38 49* 49) 97 65 76
六趟排序结果(13 27 38 49* 49 65) 97 76
七趟排序结果(13 27 38 49* 49 65 76) 97

编程实现对包含n(n>11)个元素的线性表进行简单选择排序,输出排序结果

#include
#include
using namespace std;
//自定义Person类型,存放key和n
typedef struct Person {
	string key;
	int n;
}Person;
//把Person封装Data结构里,用length来确定数组长度
typedef struct Data {
	Person *P = new Person[50];
	int length = 0;
}Data;
//初始化数组,将原始数据导入
void InitData(Data &d) {
	string a[12] = { "a","b","c","d","e","f","g","h","i","j","k" };
	int b[12] = { 62,23,28,45,77,19,50,60,18,90,66,43 };
	//循环插入,每次插入length加一
	for (int i = 0;i < 11;i++) {
		d.P[d.length].key = a[i];
		d.P[d.length].n = b[i];
		d.length++;
	}
}
//简单选择排序
void SelectSort(Data &d) {
	//一次把一个小值放在前面
	for (int i = 0;i < d.length;i++) {
		int k = i;
		for (int j = i + 1;j < d.length;j++) {
			if (d.P[j].n < d.P[k].n)
				k = j;
		}
		if (k != i) {
			Person p1 = d.P[i];
			d.P[i] = d.P[k];
			d.P[k] = p1;
		}
	}
}
//打印数组
void Print(Data &d) {
	for (int i = 0;i <= d.length - 1;i++) {
		cout << d.P[i].key << "  " << d.P[i].n << endl;
	}
}
int main() {
	Data d;
	InitData(d);
	SelectSort(d);
	Print(d);
	system("pause");
}

直接插入排序

四:直接插入排序
直接插入排序:将一条记录插入到已排好序的有序表中,从而得到一个新的,记录数量增一的有序表
数据结构实验之查找与排序_第3张图片

#include
#include
using namespace std;
typedef struct Person {
	string key;
	int n;
}Person;
typedef struct Data {
	Person *P = new Person[50];
	int length = 0;
}Data;
void InitData(Data &d) {
	string a[12] = { "a","b","c","d","e","f","g","h","i","j","k" };
	int b[12] = { 62,23,28,45,77,19,50,60,18,90,66,43 };
	for (int i = 0;i < 11;i++) {
		d.P[d.length+1].key = a[i];
		d.P[d.length+1].n = b[i];
		d.length++;
	}
}
void Print(Data &d) {
	for (int i = 1;i <= d.length;i++) {
		cout << d.P[i].key << "  " << d.P[i].n << endl;
	}
}
void InsertSort(Data &d) {
	for(int i = 2;i<=d.length;++i)
		if (d.P[i].n < d.P[i - 1].n) {
			d.P[0] = d.P[i];
			d.P[i] = d.P[i - 1];
			int j = i - 2;
			for (;d.P[0].n< d.P[j].n;--j)
				d.P[j + 1] = d.P[j];
			d.P[j + 1] =d.P[0];
		}
}
int main() {
	Data d;
	InitData(d);
	InsertSort(d);
	Print(d);
	system("pause");
}

快速排序

五:快速排序
快速排序:是由冒泡排序改进而得的。在冒泡排序过程中,只对相邻的两个记录进行比较,因此每次交换两个相邻记录时只能消除一个逆序。如果能通过两个(不相邻)记录的一次交换,消除多个逆序,则会大大加快排序的速度。快速排序方法中的一次交换可能消除多个逆序。
将待排序的n个记录中任取一个记录(通常取第一个记录)作为枢轴(支点),设其关键字为pivotkey。经过一趟排序后,把所有关键字小于PIVOTKEY的记录交换到前面,把所有关键字大于pivotkey的记录交换到后面,结构把待排序记录分成两个子表,最后将枢轴放置在分界处的位置。然后,分别对左、右子表重复上述过程,直至每一子表只有一个记录时,排序完成。
其中, 一趟快速排序的具体步骤如下:

  • 选择待排序表中的第一个记录作为枢轴, 将枢轴记录暂存 在r[0]的位置上。附设两 个指针low和high,初始时分别指向表的下界和上界(第一 趟时,low = 1; high = L.length; )
  • 从表的最右侧位置依次向左搜索,找到第一个关键字小于枢轴关键字pivotkey的记录,将其移到low处。具体操作是:当low
  • 然后再从表的最左侧位置,依次向右搜索找到第一个关键 字大于pivotkey 的记录和枢轴记录交换。具体操作是:当low
  • 重复步骤②和③,直至low与high相等为止。此时low或high的位置即为枢轴在此趟排序中的最终位置,原表被分成两个子表
  1. 编程实现对包含n(n>11)个元素的线性表进行快速排序,输出排序结果。
    例如线性有序表(19,13,47,35,67,29,50,34,18,90,10)
#include
using namespace std;
int Partition(int a[], int low, int high) {
	a[0] = a[low];
	int pivotkey = a[low];
	while (low < high) {
		while (low < high&&a[high] >= pivotkey)
			--high;
		a[low] = a[high];
		while (low < high&&a[low] <= pivotkey)
			++low;
		a[high] = a[low];
	}
	a[low] = a[0];
	return low;
}
int Func(int a[]) {
	int *m = a;
	while (*m++);
	m--;
	return(m - a);
}
void QSort(int a[], int low, int high) {
	if (low < high) {
		int pivotloc = Partition(a, low, high);
		QSort(a, low, pivotloc-1);
		QSort(a, pivotloc+1, high);
	}
}
void QuickSort(int a[]) {
	int n = Func(a);
	QSort(a, 1, n-1);
}
void Print(int a[]) {
	int n = Func(a);
	for (int i = 1;i < n;i++)
		cout << a[i]<<"   ";
	cout << endl;
}
int main() {
	int a[20] = {19,13,47,35,67,29,50,34,18,90,10 };
	Print(a);
	QuickSort(a);
	Print(a);
	system("pause");
}

在这里插入图片描述
时间精力有限,本篇博客更多的是提供代码,没有做太多的讲解,还请见谅。

你可能感兴趣的:(数据结构,数据结构,算法,二分查找,排序算法,链表)