南邮实验4(1~4题综合)各种排序算法和时间的计算

数据结构 同时被 2 个专栏收录
8 篇文章 0 订阅
13 篇文章 0 订阅

下面的代码只需要建立一个txt文件存储随机关键字即可,路径自己定义修改即可

运行结果

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

源文件


#include"堆排序的堆栈.h"

//简单排序法
//在startIndex至表尾范围内找到最小关键字的下标元素
int FindMin(List list, int startIndex)
{
	int i, minIndex = startIndex;
	for (i = startIndex+1; i < list.n; i++)
	{
		if (list.D[i].key < list.D[minIndex].key)
		{
			minIndex = i;
		}
	}
	return minIndex;
}
//交换顺序表中两个元素位置
void swap(Entry * D, int i, int j)
{
	Entry temp;
	if (i == j)
		return;
	temp = *(D + i);
	*(D + i) = *(D + j);
	*(D + j) = temp;
}

//实现简单排序算法,完成,
//简单排序算法的最好最坏和平均情况的时间复杂度都是O(n^2),空间复杂度都是O(1)
void SelectionSort(List* list)
{
	int minIndex=0, startIndex = 0;
	while (startIndex < list->n - 1)
	{
		minIndex = FindMin(*list, startIndex);
		swap(list->D, startIndex, minIndex);
		startIndex++;
	}
	printf("\n简单排序后的list为:\n");
}


//直接插入排序算法  完成
// 最好的时间复杂度是O(n),最坏和平均的时间复杂度为O(n^2),空间复杂度为O(1)
void InsertSort(List* list)
{
	int i, j;     //i为待插入元素下标
	Entry insertItem;     //每一趟待插入元素
	for (i = 1; i < list->n; i++)
	{
		insertItem = list->D[i];
		for (j = i - 1; j >= 0; j--)
		{
			if (insertItem.key < list->D[j].key)
				list->D[j + 1] = list->D[j];
			else
				break;
		}
		list->D[j + 1] = insertItem;  //待插入元素有序存放至有序列表中
	}
	printf("\n直接插入排序后的list为:\n");
}


//冒泡排序法  完成,
//最好的时间复杂度是O(n),最坏和平均的时间复杂度为O(n^2),空间复杂度为O(1)
void BubbleSort(List* list)
{
	int i, j;
	for (i = list->n - 1; i > 0; i--)
	{
		BOOL isSwap = FALSE;
		for (j = 0; j < i; j++)
		{
			if (list->D[j].key > list->D[j + 1].key)
			{
				swap(list->D, j, j + 1);
				isSwap = TRUE;
			}
		}
		if (!isSwap)
			break;   //如果本趟排序没有发生元素交换,排序完成
	}
	printf("\n冒泡排序后的list为:\n");
}


//快速排序法  完成
//最好和平均复杂度为O(n*log2 n),最坏的时间复杂度为O(n^2),最好和平均情况下空间复杂度为O(log2 n),最坏的情况下为O(n)

//序列化分方法
int Partition(List* list, int low, int high)
{
	int i = low, j = high+1;
	Entry pivot = list->D[low];
	do
	{
		do
		{
			i++;
		} while (i <= high && list->D[i].key < pivot.key);
		do
		{
			j--;
		} while (list->D[j].key > pivot.key);
		if (i < j)
			swap(list->D, i, j);
	} while (i < j);
	swap(list->D, low, j);
	return j;


	/*
	int i = low, j = high + 1;
	Entry pivot = list->D[low]; //pivot 是分割元素
	do
	{
		do i++;
		while (i <= high && list->D[i].key < pivot.key);   //i前进
		do j--;
		while (list->D[j].key > pivot.key); //j前进
		if (i < j)
			swap(list->D, i, j);
	} while (i < j);
	swap(list->D, low, j);
	return j;  //此式j是分割元素下标
	*/
}

//快速排序算法  
void QuickSort(List* list, int low, int high)
{
	int k;
	if (low < high)   //当前待排序序列至少包含2个元素
	{
		k = Partition(list, low, high);
		QuickSort(list, low, k - 1);
		QuickSort(list, k + 1, high);
	}
}
void QuickSort(List* list)
{
	QuickSort(list, 0, list->n - 1);
	printf("\n快速排序后的list为:\n");
}

//两路合并排序算法

//序列两路合并方法
void Merge(List* list, Entry* temp, int low, int n1, int n2)
{
	int i = low, j = low + n1; //i和j初始分别指向两个序列的第一个元素
	while (i <= low + n1 - 1 && j <= low + n1 + n2 - 1)
	{
		if (list->D[i].key <= list->D[j].key)
		{
			*temp++ = list->D[i++];
		}
		else
		{
			*temp++ = list->D[j++];
		}
	}
	while (i <= low + n1 - 1)
	{
		*temp++ = list->D[i++];
	}
	while (j <= low + n1 + n2 - 1)
	{
		*temp++ = list->D[j++];
	}
}
//两路合并排序算法
void MergeSort(List* list)
{
	Entry temp[MaxSize];
	int low, n1, n2, i, size = 1;
	while (size < list->n)
	{
		low = 0;
		while (low + size < list->n)
		{
			n1 = size;
			if (low + 2 * size < list->n)
				n2 = size;
			else
				n2 = list->n - low-size;
			Merge(list, temp+low, low, n1, n2);
			low += n1 + n2;
		}
		for (i = 0; i < low; i++)
		{
			list->D[i] = temp[i];  //复制一趟合并排序结果
		}
		size *= 2;  //子序列长度翻倍
	}
	printf("\n两路合并排序后的list为:\n");
}

//堆排序算法  已完成
void HeapSort(List* list)
{
	int i;
	PriorityQueue PQ;
	CreatePQ(&PQ, list->n);
	for (i = 0; i < list->n; i++)
	{
		Append(&PQ, list->D[i]);
	}
	/*
	for (i = 0; i < PQ.n; i++)
	{
		printf("%d ", PQ.elements[i]);
	}
	*/
	for (i = PQ.n - 1; i > 0; i--)
	{
		queue_swap(PQ.elements, 0, i);
		AdjustDown(PQ.elements, 0, i -1);
		//printf("%d ", PQ.elements[0]);
	}
	printf("\n堆排序后的list为:\n");
	/*
	for (i = 0; i < PQ.n; i++)
	{
		printf("%d ", PQ.elements[i]);
	}
	*/
}



//产生n个随机关键字,并存入文件:
void create_key(int num)
{
	clock_t start, end;
	double duration;
	start = clock();
	int* key_list = (int*)malloc(sizeof(int) * num);
	int i;
	srand(time(NULL));
	for (i = 0; i < num; i++)
	{
		key_list[i] = rand()%1000;
	}
	FILE* fp;
	fopen_s(&fp, "C:\\Users\\HP\\Desktop\\数据结构实验4\\suiji.txt", "w");
	if (fp == 0)
	{
		printf("\nfile error!\n");
		exit(1);
	}
	for (i = 0; i < num; i++)
	{
		fprintf_s(fp, "%d%c", key_list[i],' ');
	}
	fclose(fp);
	printf("\n随机关键字存储完毕!");
	free(key_list);
	end = clock();
	duration = double(end - start);
	printf(",存入文件txt中所花费的时间是%lfms\n", duration);
}

void keep_in_list(List* list,int num)
{
	FILE* fp;
	int i = 0;
	char c = ' ';
	Entry E;
	KeyType temp;
	fopen_s(&fp, "C:\\Users\\HP\\Desktop\\数据结构实验4\\suiji.txt", "r");
	if (fp == 0)
	{
		printf("file error!!\n");
		exit(1);
	}
	while (i < num)
	{
		fscanf_s(fp, "%d%c", &temp, &c);
		//printf("%d ", temp);
		Entry E;
		E.data = 0;
		E.key = temp;
		list->D[list->n++] = E;
		i++;
	}


	/*
	char str[500] = {};
	char temp[10] = {};
	int k = 0;
	int data;
	Entry E;
	fgets(str, 500, fp);
	for (int i = 0; !feof(fp); i++)
	{

		if (str[i] != ' ')
		{
			temp[k++] = str[i];
			temp[k] = '\0';
		}
		else
		{
			data = atoi(temp);
			E.data = 0;
			E.key = data;
			list->D[list->n++] = E;
			k = 0;
		}
		if (str[i + 1] == '\0')
		{
			fgets(str, 500, fp);
			i = -1;
		}
	}
	*/
}
void Print(List list)
{
	for (int i = 0; i < list.n; i++)
	{
		printf("%d ", list.D[i].key);
	}
	printf("\n");
}

void main()
{
	List list;
	InitList(&list);
	int num;
	clock_t start, end;
	double duration;
	printf("请输入产生随机关键字的总数\t");
	scanf_s("%d", &num);
	create_key(num);  //产生随机关键字
	keep_in_list(&list, num);
	printf("\n原随机关键字为:\n");
	Print(list);

	//简单排序:
	start = clock();
	InitList(&list);
	keep_in_list(&list, num);  //从文件中读取关键字存入list中
	SelectionSort(&list);
	Print(list);
	DestoryList(&list);
	end = clock();
	duration = double(end - start);
	printf("简单排序%d个关键字所花费的时间为%lf:\n",num, duration);

	//直接插入排序
	start = clock();
	InitList(&list);
	keep_in_list(&list, num);
	InsertSort(&list);
	Print(list);
	DestoryList(&list);
	end = clock();
	duration = double(end - start);
	printf("直接插入排序%d个关键字所花费的时间为%lf:\n", num, duration);
	
	//冒泡排序
	start = clock();
	InitList(&list);
	keep_in_list(&list, num);
	BubbleSort(&list);
	Print(list);
	DestoryList(&list);
	end = clock();
	duration = double(end - start);
	printf("冒泡排序%d个关键字所花费的时间为%lf:\n", num, duration);

	//快速排序
	start = clock();
	InitList(&list);
	keep_in_list(&list, num);
	QuickSort(&list);
	Print(list);
	DestoryList(&list);
	end = clock();
	duration = double(end - start);
	printf("快速排序%d个关键字所花费的时间为%lf:\n", num, duration);

	//两路合并排序
	start = clock();
	InitList(&list);
	keep_in_list(&list, num);
	MergeSort(&list);
	Print(list);
	DestoryList(&list);
	end = clock();
	duration = double(end - start);
	printf("两路合并排序%d个关键字所花费的时间为%lf:\n", num, duration);

	//堆排序
	start = clock();
	InitList(&list);
	keep_in_list(&list, num);
	HeapSort(&list);
	DestoryList(&list);
	end = clock();
	duration = double(end - start);
	printf("\n堆排序%d个关键字所花费的时间为%lf:\n", num, duration);
}

堆排序的堆栈.h

#pragma once
#include"排序算法基础结构.h"
typedef struct priorityQueue
{
	Entry* elements;
	int n;
	int maxSize;
}PriorityQueue;
void AdjustUp(Entry heap[], int current)
{
	int p = current;
	Entry temp;
	while (p > 0)
	{
		if (heap[p].key > heap[(p - 1) / 2].key)
		{
			temp = heap[p];
			heap[p] = heap[(p - 1) / 2];
			heap[(p - 1) / 2] = temp;
			p = (p - 1) / 2;  //将p向上移动至当前考查元素的双亲节点位置
		}
		else  //若p指向的元素不小于其双亲节点,则调整完毕
			break;
	}
}
void AdjustDown(Entry heap[], int current, int border)
{
	int p = current;
	int maxChild;
	Entry temp;
	while (2 * p + 1 <= border)
	{
		if ((2 * p + 2 <= border) && (heap[2 * p + 2].key > heap[2 * p + 1].key))
		{
			maxChild = 2 * p + 2;
		}
		else
		{
			maxChild = 2 * p + 1;
		}
		if (heap[p].key >= heap[maxChild].key)
		{
			break;
		}
		else
		{
			temp = heap[p];
			heap[p] = heap[maxChild];
			heap[maxChild] = temp;
			p = maxChild;
		}
	}
}

//创建一个空的优先权队列
void CreatePQ(PriorityQueue* PQ, int mSize)
{
	PQ->maxSize = mSize;
	PQ->n = 0;
	PQ->elements = (Entry*)malloc(mSize * sizeof(Entry));
}

// 销毁一个优先权队列,释放其占用的空间
void Destory(PriorityQueue* PQ)
{
	free(PQ->elements);
	PQ->n = 0;
	PQ->maxSize = 0;
}

//判断优先权队列是否为空
BOOL IsEmpty(PriorityQueue* PQ)
{
	if (PQ->n == 0)
		return TRUE;
	else
		return FALSE;
}

//判断优先权队列是否已满
BOOL IsFull(PriorityQueue* PQ)
{
	if (PQ->n == PQ->maxSize)
		return TRUE;
	else
		return FALSE;
}

//获取当前优先权队列中的元素的数量
int Size(PriorityQueue* PQ)
{
	return PQ->n;
}

//在优先权队列中增加一个新元素x
void Append(PriorityQueue* PQ, Entry x)
{
	if (IsFull(PQ))
		return;
	PQ->elements[PQ->n] = x;
	PQ->n++;
	AdjustUp(PQ->elements, PQ->n - 1);
}

//取出优先级最高的元素,利用参数x返回,并在优先权队列中删除该元素
void Serve(PriorityQueue* PQ, Entry* x)
{
	if (IsEmpty(PQ))
		return;
	*x = PQ->elements[0];
	PQ->n--;
	PQ->elements[0] = PQ->elements[PQ->n];
	AdjustDown(PQ->elements, 0, PQ->n - 1);
}

void queue_swap(Entry *E, int start, int last)
{
	Entry temp = E[start];
	E[start] = E[last];
	E[last] = temp;
}

排序算法基础结构.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<time.h>

typedef int KeyType;
typedef int DataType;
typedef int BOOL;
#define FALSE 0
#define TRUE 1
#define MaxSize 100000

typedef struct entry
{
	KeyType key;
	DataType data;
}Entry;
typedef struct list
{
	int n;
	Entry *D;
}List;

void InitEntry(Entry* E, KeyType key, DataType data)
{
	E->data = data;
	E->key = key;
}
void InitList(List* list)
{
	list->n = 0;
	list->D = (Entry*)malloc(sizeof(Entry) * MaxSize);
}
void DestoryList(List* list)
{
	list->n = 0;
	free(list->D);
}
void listAppend(List* list, Entry E)
{
	if (list->n < MaxSize)
	{
		list->D[list->n++] = E;
	}
	else
	{
		return;
	}
}
展开阅读全文
  • 3
    点赞
  • 7
    评论
  • 1
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
©️2020 CSDN 皮肤主题: 1024 设计师:白松林 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值