C语言:(数据结构)较简明地实现随机生成MAXSIZE个整型数据,进行冒泡排序/快速排序。(较稳定)

2021年12月15日优化:

再优化:“C语言:(数据结构)较简明地实现随机生成MAXSIZE个整型数据,进行冒泡排序/快速排序。(较稳定)“_Xavier.S的博客-CSDN博客

2021年12月14日 14:25改良完成。

改良处:优化了原来快速排序的输出情况,即:避免了将每一次循环结果输出。

一、冒泡排序原理:

        冒泡法是一种简单的排序方法,它的实现非常简单。首先对n个项目进行扫描,比较相领两个项目的大小,若发现违背大小次序则进行互换,由此可以使n个项目中的最大者换到最后。

        然后对剩下的未排序好的项目再进行扫描,使它们的最大者换到表的最后。以此类推,直到将表全部排序好为止。这种排序方法,每遍扫描以后,都缩短了待排序表的长度,如果在某次扫描过程中,没有发现交换,则排序结束。

具体步骤:

1、从后往前依次比较相邻的元素。若是要按照升序排序,则后面的元素比前面的小,就交换这2个元素;降序则相反。

2、对每一对相邻元素作同样的工作,从第一对到最后一对。进行一轮比较交换下来,最后的元素就会是最小(或最大)的数了,这个数就不用参与后面的比较操作了。

3、针对所有的元素重复以上的步骤。

4、持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

为了尽量缩短待排序表的长度,避免下一次扫描中可能出现的不必要的比较,在每次扫描过程中,一方面要记录进行元素交换的次数,另一方面要记住在本次扫描中的最后一次进行交换的位置。在这个位置以后没有发生过交换,则说明在这个位置以后的元素实际上已经排好次序。

总的来说,冒泡法基本思想是重复的进行整个数组的排序,一次比较两个元素(两两排序),如果它们顺序不符合就交换,重复这样直到数列没有再需要交换的数为止(结束条件)。因为它就好像泡泡一样,轻的气泡会往上漂浮,在不断漂浮的过程中,发生了两两交换过程,所以叫冒泡排序。

(参考:冒泡排序算法原理-电子发烧友网

二、快速排序原理:

通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小。

然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

假设要排序的数组是A[1]……A[N],首先任意选取一个数据(通常选用第一个数据)作为关键数据,然后将所有比它的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一躺快速排序。一躺快速排序的算法是:

1、设置两个变量I、J,排序开始的时候I:=1,J:=N;

2、以第一个数组元素作为关键数据,赋值给X,即X:=A[1];

3、从J开始向前搜索,即由后开始向前搜索(J:=J-1),找到第一个小于X的值,两者交换;

4、从I开始向后搜索,即由前开始向后搜索(I:=I+1),找到第一个大于X的值,两者交换;

5、重复第3、4步,直到I=J。

 例如:

        设要排序的数组是A[0]……A[N-1],首先任意选取一个数据(通常选用数组的第一个数)作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序。

        值得注意的是,快速排序不是一种稳定的排序算法,也就是说,多个相同的值的相对位置也许会在算法结束时产生变动。

一趟快速排序的算法是:

1、设置两个变量i、j,排序开始的时候:i=0,j=N-1;

2、以第一个数组元素作为关键数据,赋值给key,即key=A[0];

3、从j开始向前搜索,即由后开始向前搜索(j--),找到第一个小于key的值A[j],将A[j]的值赋给A[i];

4、从i开始向后搜索,即由前开始向后搜索(i++),找到第一个大于key的A[i],将A[i]的值赋给A[j];

5、重复第3、4步,直到i=j; (3,4步中,没找到符合条件的值,即3中A[j]不小于key,4中A[i]不大于key的时候改变j、i的值,使得j=j-1,i=i+1,直至找到为止。找到符合条件的值,进行交换的时候i, j指针位置不变。

(参考:快速排序算法原理与实现_百度知道

三、代码实现:

以下MAXSIZE以20为例。

随机数生成、创建数组:

int *CreatArray()
{
	int *arr = (int*)malloc(sizeof(unsigned int)*MAXSIZE);
	srand((unsigned int)time(NULL));
	for (int i = 0; i < MAXSIZE; i++) {
		int randNum = rand() % MAXSIZE;
		arr[i] = randNum;
      printf("%d ", arr[i]);
	}
	return arr;
}

冒泡排序函数:

void BubbleSort(int a[MAXSIZE])
{
    int i,j,temp;
    for(i=0;i<MAXSIZE-1;i++)
    {
        for(j=0;j<MAXSIZE-i-1;j++)
        {
            if(a[j]<a[j+1]) ///比较大小并交换
            {
                temp=a[j];
                a[j]=a[j+1];
                a[j+1]=temp;
            }
        }
    }
    for(i=0;i<MAXSIZE;i++)
    printf("%d ",a[i]);
    printf("\n");
}

快速排序、打印排序后数组元素 函数 改进前:

快速排序函数:(初级版)

存在问题:将每一次循环的结果都输出。十分费时、费内存,糟糕极了。

///快速排序
void QuickSort(int arr[MAXSIZE],int start,int end) {
	int i = start;
	int j = end;
	int temp = arr[start];	///基准数
	if (i < j) {
		while(i < j){
///从右向左去找比基准数小的元素
			while (i < j&&arr[j]>=temp)
            {j--;}
			///填坑
			if (i < j) {
				arr[i] = arr[j];
				i++;
			}
///从左向右 找比基准数大的数
			while (i < j&&arr[i] <= temp)
            {i++;}
			///填坑
			if (i < j) {
				arr[j] = arr[i];
				j--;
			}
			Display(arr,MAXSIZE);
		}
///把基准数放到i=j的位置
		arr[i] = temp;
///对左半部分(递归)进行快速排序
		QuickSort(arr, start, i - 1);
///对右部分(递归)进行快速排序
		QuickSort(arr, j + 1, end);
		Display(arr,MAXSIZE);
	}
}

打印排序后数组元素:

void Display(int a[],int n){
    int i;
    for(i=0; i<n ;i++)
	printf("%d ",a[i]);
	printf("\n");
}

主函数(测试函数):

void main()
{
    int arr[MAXSIZE]; int choose;
    printf("随机生成de数\n");
    arr[MAXSIZE]=CreatArray();
    printf("\n输入数字1、2依次选择冒泡、快速排序\n");
    scanf("%d",&choose);
    switch(choose)
    {
    case 1:
            printf("冒泡排序(HIGN-->LOW)\n");
            BubbleSort(arr[MAXSIZE]);
            printf("\n");
            break;
    case 2:
            printf("快速排序(LOW-->HIGN)\n");
            QuickSort(arr[MAXSIZE],0,MAXSIZE);
            printf("\n");
            break;
    }
}

完整代码:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
///定义最大数值(数组的最大长度)
#define MAXSIZE 20

///创建数组
int *CreatArray()
{
	int *arr = (int*)malloc(sizeof(unsigned int)*MAXSIZE);
	srand((unsigned int)time(NULL));
	for (int i = 0; i < MAXSIZE; i++) {
		int randNum = rand() % MAXSIZE;
		arr[i] = randNum;
      printf("%d ", arr[i]);
	}
	return arr;
}

///冒泡排序
void BubbleSort(int a[MAXSIZE])
{
    int i,j,temp;
    for(i=0;i<MAXSIZE-1;i++)
    {
        for(j=0;j<MAXSIZE-i-1;j++)
        {
            if(a[j]<a[j+1]) ///比较大小并交换
            {
                temp=a[j];
                a[j]=a[j+1];
                a[j+1]=temp;
            }
        }
    }
    for(i=0;i<MAXSIZE;i++)
    printf("%d ",a[i]);
    printf("\n");
}

///快速排序
void QuickSort(int arr[MAXSIZE],int start,int end) {
	int i = start;
	int j = end;
	int temp = arr[start];	///基准数
	if (i < j) {
		while(i < j){
///从右向左去找比基准数小的元素
			while (i < j&&arr[j]>=temp)
            {j--;}
			///填坑
			if (i < j) {
				arr[i] = arr[j];
				i++;
			}
///从左向右 找比基准数大的数
			while (i < j&&arr[i] <= temp)
            {i++;}
			///填坑
			if (i < j) {
				arr[j] = arr[i];
				j--;
			}
			Display(arr,MAXSIZE);
		}
///把基准数放到i=j的位置
		arr[i] = temp;
///对左半部分(递归)进行快速排序
		QuickSort(arr, start, i - 1);
///对右部分(递归)进行快速排序
		QuickSort(arr, j + 1, end);
		Display(arr,MAXSIZE);
	}
}

void Display(int a[],int n){
    int i;
    for(i=0; i<n ;i++)
	printf("%d ",a[i]);
	printf("\n");
}


void main()
{
    int arr[MAXSIZE]; int choose;
    printf("随机生成de数\n");
    arr[MAXSIZE]=CreatArray();
    printf("\n输入数字1、2依次选择冒泡、快速排序\n");
    scanf("%d",&choose);
    switch(choose)
    {
    case 1:
            printf("冒泡排序(HIGN-->LOW)\n");
            BubbleSort(arr[MAXSIZE]);
            printf("\n");
            break;
    case 2:
            printf("快速排序(LOW-->HIGN)\n");
            QuickSort(arr[MAXSIZE],0,MAXSIZE);
            printf("\n");
            break;
    }
}

运行结果:

冒泡排序: 

快速排序(待改进):

由此可见,非常耗时,还待改进。

2021年12月14日 12:52:13 

快速排序、打印排序后数组元素 函数 改进后:

快速排序函数:

int QuickSort(int arr[MAXSIZE],int start,int end) {
	int i = start;
	int j = end;
	int temp = arr[start];	///基准数
	if (i < j) {
		while(i < j){
///从右向左去找比基准数小的元素
			while (i < j&&arr[j]>=temp)
            {j--;}
			///填坑
			if (i < j) {
				arr[i] = arr[j];
				i++;
			}
///从左向右 找比基准数大的数
			while (i < j&&arr[i] <= temp)
            {i++;}
			///填坑
			if (i < j) {
				arr[j] = arr[i];
				j--;
			}
		}
///把基准数放到i=j的位置
		arr[i] = temp;
///对左半部分(递归)进行快速排序
		QuickSort(arr, start, i - 1);
///对右部分(递归)进行快速排序
		QuickSort(arr, j + 1, end);
	}else
	{return arr;} ///改进的地方
}

改进的地方: 

        增加return语句 为下面主函数中调用Display打印函数提供了条件。

打印排序后数组元素:(与改进前毫无变化)

void Display(int a[],int n){
    int i;
    for(i=0; i<n ;i++)
	printf("%d ",a[i]);
	printf("\n");
}

主函数(测试函数):

void main()
{
    int arr[MAXSIZE]; int choose;
    printf("随机生成de数\n");
    arr[MAXSIZE]=CreatArray();
    printf("\n输入数字1、2依次选择冒泡、快速排序\n");
    scanf("%d",&choose);
    switch(choose)
    {
    case 1:
            printf("冒泡排序(HIGN-->LOW)\n");
            BubbleSort(arr[MAXSIZE]);
            break;
    case 2:
            printf("快速排序(LOW-->HIGN)\n");
            Display(QuickSort(arr[MAXSIZE],0,MAXSIZE),MAXSIZE);///改进的地方
            break;
    }
}

改进的地方: 

        将Display打印函数放在主函数的switch中,这样就避免将每一次循环的结果输出打印了。

完整代码:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
///定义最大数值(数组的最大长度)
#define MAXSIZE 20

///创建数组
int *CreatArray()
{
	int *arr = (int*)malloc(sizeof(unsigned int)*MAXSIZE);
	srand((unsigned int)time(NULL));
	for (int i = 0; i < MAXSIZE; i++) {
		int randNum = rand() % MAXSIZE;
		arr[i] = randNum;
      printf("%d ", arr[i]);
	}
	return arr;
}

///冒泡排序
void BubbleSort(int a[MAXSIZE])
{
    int i,j,temp;
    for(i=0;i<MAXSIZE-1;i++)
    {
        for(j=0;j<MAXSIZE-i-1;j++)
        {
            if(a[j]<a[j+1]) ///比较大小并交换
            {
                temp=a[j];
                a[j]=a[j+1];
                a[j+1]=temp;
            }
        }
    }
    for(i=0;i<MAXSIZE;i++)
    printf("%d ",a[i]);
    printf("\n");
}

///快速排序
int QuickSort(int arr[MAXSIZE],int start,int end) {
	int i = start;
	int j = end;
	int temp = arr[start];	///基准数
	if (i < j) {
		while(i < j){
///从右向左去找比基准数小的元素
			while (i < j&&arr[j]>=temp)
            {j--;}
			///填坑
			if (i < j) {
				arr[i] = arr[j];
				i++;
			}
///从左向右 找比基准数大的数
			while (i < j&&arr[i] <= temp)
            {i++;}
			///填坑
			if (i < j) {
				arr[j] = arr[i];
				j--;
			}
		}
///把基准数放到i=j的位置
		arr[i] = temp;
///对左半部分(递归)进行快速排序
		QuickSort(arr, start, i - 1);
///对右部分(递归)进行快速排序
		QuickSort(arr, j + 1, end);
	}else
	{return arr;}
}

void Display(int a[],int n){
    int i;
    for(i=0; i<n ;i++)
	printf("%d ",a[i]);
	printf("\n");
}


void main()
{
    int arr[MAXSIZE]; int choose;
    printf("随机生成de数\n");
    arr[MAXSIZE]=CreatArray();
    printf("\n输入数字1、2依次选择冒泡、快速排序\n");
    scanf("%d",&choose);
    switch(choose)
    {
    case 1:
            printf("冒泡排序(HIGN-->LOW)\n");
            BubbleSort(arr[MAXSIZE]);
            break;
    case 2:
            printf("快速排序(LOW-->HIGN)\n");
            Display(QuickSort(arr[MAXSIZE],0,MAXSIZE),MAXSIZE);
            break;
    }
}

运行结果:

冒泡排序:

快速排序:

四、总结:

        回顾此次探究实验,明白了每一段代码都有其独特的重要作用,马虎大意不得,一丝丝的颠倒或者错误都会导致“牵一发而动全身”。在以后的学习生活中,要重视基础,打牢基础,多实践、动手,多探究并善于反思。否则一切都将是“豆腐渣工程”。

        纸上得来终觉浅,绝知此事要躬行。

\int_{born}^{die}f(you-My.Dear,me)d(time)=Love

\int_{now}^{future}f(hardworking)d(time)=Happiness

未尽事宜,敬请见谅。

欢迎联系我,提出您的宝贵意见。

谢谢观看!

By:Xavier.S

QQ:2543756155

E-mail:asztmicro@outlook.com

2021年12月14日 14:49:48

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用C语言创建顺序表的基本步骤: 1. 定义顺序表结构体 ```c #define MAXSIZE 100 // 定义顺序表的最大长度 typedef struct { int data[MAXSIZE]; // 存储元素的数组 int length; // 当前顺序表的长度 } SqList; // 定义顺序表类型 ``` 2. 初始化顺序表 ```c void InitList(SqList *L) { int i; for (i = 0; i < MAXSIZE; i++) { L->data[i] = 0; // 将元素全部置为0,表示顺序表为空 } L->length = 0; // 初始化顺序表长度为0 } ``` 3. 插入元素 ```c int ListInsert(SqList *L, int pos, int elem) { int i; if (pos < 1 || pos > L->length + 1) { // 判断插入位置是否合法 return 0; } if (L->length >= MAXSIZE) { // 判断顺序表是否已满 return 0; } for (i = L->length; i >= pos; i--) { // 将插入位置后的元素向后移动一个位置 L->data[i] = L->data[i - 1]; } L->data[pos - 1] = elem; // 插入新元素 L->length++; // 顺序表长度加1 return 1; } ``` 4. 删除元素 ```c int ListDelete(SqList *L, int pos) { int i; if (pos < 1 || pos > L->length) { // 判断删除位置是否合法 return 0; } for (i = pos - 1; i < L->length - 1; i++) { // 将删除位置后的元素向前移动一个位置 L->data[i] = L->data[i + 1]; } L->length--; // 顺序表长度减1 return 1; } ``` 5. 获取元素 ```c int GetElem(SqList *L, int pos) { if (pos < 1 || pos > L->length) { // 判断获取位置是否合法 return 0; } return L->data[pos - 1]; // 返回指定位置的元素值 } ``` 6. 遍历顺序表 ```c void TraverseList(SqList *L) { int i; for (i = 0; i < L->length; i++) { printf("%d ", L->data[i]); // 输出每个元素的值 } printf("\n"); } ``` 7. 完整代码 ```c #include <stdio.h> #define MAXSIZE 100 // 定义顺序表的最大长度 typedef struct { int data[MAXSIZE]; // 存储元素的数组 int length; // 当前顺序表的长度 } SqList; // 定义顺序表类型 void InitList(SqList *L) { int i; for (i = 0; i < MAXSIZE; i++) { L->data[i] = 0; // 将元素全部置为0,表示顺序表为空 } L->length = 0; // 初始化顺序表长度为0 } int ListInsert(SqList *L, int pos, int elem) { int i; if (pos < 1 || pos > L->length + 1) { // 判断插入位置是否合法 return 0; } if (L->length >= MAXSIZE) { // 判断顺序表是否已满 return 0; } for (i = L->length; i >= pos; i--) { // 将插入位置后的元素向后移动一个位置 L->data[i] = L->data[i - 1]; } L->data[pos - 1] = elem; // 插入新元素 L->length++; // 顺序表长度加1 return 1; } int ListDelete(SqList *L, int pos) { int i; if (pos < 1 || pos > L->length) { // 判断删除位置是否合法 return 0; } for (i = pos - 1; i < L->length - 1; i++) { // 将删除位置后的元素向前移动一个位置 L->data[i] = L->data[i + 1]; } L->length--; // 顺序表长度减1 return 1; } int GetElem(SqList *L, int pos) { if (pos < 1 || pos > L->length) { // 判断获取位置是否合法 return 0; } return L->data[pos - 1]; // 返回指定位置的元素值 } void TraverseList(SqList *L) { int i; for (i = 0; i < L->length; i++) { printf("%d ", L->data[i]); // 输出每个元素的值 } printf("\n"); } int main() { SqList list; InitList(&list); ListInsert(&list, 1, 10); ListInsert(&list, 2, 20); ListInsert(&list, 3, 30); TraverseList(&list); ListDelete(&list, 2); TraverseList(&list); printf("%d\n", GetElem(&list, 2)); return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值