Linux C学习笔记-排序问题

本文详细介绍了C语言中的三种经典排序算法:冒泡排序、插入排序和选择排序。冒泡排序通过相邻元素两两比较交换实现排序,时间复杂度为O(n^2)。插入排序则是通过构建有序序列逐步插入未排序元素,同样具有O(n^2)的时间复杂度。选择排序则是在未排序部分寻找最小元素并放到已排序部分末尾,同样保持O(n^2)的时间复杂度。这些算法虽然效率相对较低,但理解简单,适合初学者学习。
摘要由CSDN通过智能技术生成

i++,++i

(1)for循环内部语句中的i++和++i:

比如说for(i=0; i<9; i++)与for(i=0; i<9; ++i),都表示每次for循环结束后判断i是否小于9,再进入下一次循环。

(2)++i是先改变i的值即加1后再使用i的值;而i++是先使用i的值在改变它的值即加。

排序问题

C 数据结构之十大排序 三大查找

必学十大经典排序算法,看这篇就够了(C++版本)

相关概念描述

排序算法的评价指标:主要看时间复杂度和空间复杂度,以及算法自身的复杂度。

时间复杂度:一个算法执行所消耗的时间。

空间复杂度:运行完一个算法所需的内存大小。

冒泡排序:

冒泡排序是通过集合内相邻两个元素两两比较来排序的,每一次比较都是从位于集合内的前两个元素开始的,只不过每次需要比较的长度减1。如果比较的两个元素相等,则不进行交换。

  • 第一次排序的比较次数:n-1,n个元素的相邻两两比较;
  • 第二次排序的比较次数:n-2,第一次排序后最后一个元素可以确定为最大值,不再参与第二次排序;
  • 第n-1次排序的比较次数:1;
  • 总的比较次数:(n-1)+(n-2)+...+1=n*(n-1)/2。

所以冒泡排序的时间复杂度是O(n^2),空间复杂度是O(1)。

示例代码一如下:

#include <stdio.h>
void bubble_sort(int arr[], int len) {
    int i, j, temp;
    for (i = 0; i < len - 1; i++)
        for (j = 0; j < len - 1 - i; j++)
            if (arr[j] > arr[j + 1]) {
                temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
}
int main() {
    int arr[] = { 22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70 };
    int len = (int) sizeof(arr) / sizeof(*arr);
    bubble_sort(arr, len);
    int i;
    for (i = 0; i < len; i++)
        printf("%d ", arr[i]);
    return 0;
}

示例代码二如下:(这个是自己写的。注意两个for循环的作用。

#include<stdio.h>
int main()
{
	int a[5] = {436,21,62,32,-44};
	int n = sizeof(a)/sizeof(a[0]);
	//int i;
	for(int i=0; i<n-1; i++)       //比较的轮数,总共要比较n-1轮。
	{
		//因为每次比较的次数都要减 1,刚好 i 每次加 1,所以每一轮比较的次数是 n-i-1
		for(int j=0; j<n-i-1; j++)  //每一轮需要比较的次数
		{
			if(a[j]>a[j+1])         //如果前面的元素比后面的元素大,则交换位置
			{
				int tmp = a[j];
				a[j] = a[j+1];
				a[j+1] = tmp;
			}
		}
	}
	printf("排序后的数组为:\n");
	for(int i=0;i<n;i++)
	{
	    printf("%d\t",a[i]);
	}
	return 0;
}

插入排序:

工作原理:通过构建有序序列,对于未排序数据,在已排序列中从后向前扫描,找到相应位置并插入。

第1个元素,需要进行 0 次比较;
第2个元素,需要进行 1 次比较;
第3个元素,需要进行 2 次比较;
第n个元素,需要进行n-1次比较;

所以插入排序的时间复杂度是O(n^2),空间复杂度是O(1)。

void insertion_sort(int arr[], int len) 
{
    int i, j, temp;
    for (i = 1; i < len; i++) 
    {
        temp = arr[i];
        for (j = i - 1; j >= 0 && arr[j] > temp; j--)
        {
            arr[j+1] = arr[j];
        }
        arr[j+1] = temp;
    }
}

选择排序:

工作原理:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。时间复杂度是 O(n^2)。 空间复杂度是 O(1) 。

void selection_sort(int a[], int len) 
{
    int i,j,temp;
 
    for (i = 0 ; i < len - 1 ; i++) 
    {
        int min = i;                  // 记录最小值,第一个元素默认最小
        for (j = i + 1; j < len; j++)     // 访问未排序的元素
        {
            if (a[j] < a[min])    // 找到目前最小值
            {
                min = j;    // 记录最小值
            }
        }
        if(min != i)
        {
            swap(&a[min], &a[i]);    // 使用自定义函数交換两个变量
        }        
    }
}
 
void swap(int *a,int *b) // 交换两个变量
{
    int temp = *a;
    *a = *b;
    *b = temp;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值