目录
冒泡排序:
-
核心思想:两个相邻的元素进行比较
-
分析过程:

- 易错点:
1.传递的参数是数组和数组的个数(长度)--数组的个数无法在函数内部计算
2.双层的for循环,第二层的for循环中:j是随着i变化的 -
void bubble_sort(int arr[],int nlen)//形参是数组的形式 { for (int i = 0; i < nlen - 1; i++)//一共交换多少趟 { for (int j = 0; j < nlen - 1 - i; j++)//每趟里面的元素交换 { if (arr[j] > arr[j + 1]) { //交换 int temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } } int main() { //int arr[] = { 9,8,7,6,5,4,3,2,1 }; int arr[] = { 5,1,4,7,0,9,11,73,54 }; int nlen = sizeof(arr) / sizeof(arr[0]); bubble_sort(arr,nlen);//传进来的数组是数组首元素的地址 for (int i = 0; i < nlen; i++) { printf("%d ", arr[i]); } printf("\n"); return 0; }快速排序:
-
核心思想:通过一趟排序,将待排元素分割成两个独立的部分,分别对这两部分进行排序,达到有序。
-
步骤:挖坑填数法!+分治的思想
1.先找到基准元素(1),把比基准元素小的,放到基准元素的左边;把比基准元素大的,放到基准元素的右边,此时将基准元素(1)排到正确的位置
2.寻找新的基准元素(2),递归实现
3.寻找新的基准元素(3),递归实现 -
图文分析:

int AdjustArray(int s[], int l, int r) //返回调整后基准数的位置
{
int i = l, j = r;
int x = s[l]; //s[l]即s[i]就是第一个坑
//由于s[l]这个位置的数被记录下来了,所以可以认为这个位置是一个坑
while (i < j)
{
// 从右向左找小于x的数来填s[i]
while(i < j && s[j] >= x)
j--;
if(i < j)
{
s[i] = s[j]; //将s[j]填到s[i]中,s[j]就形成了一个新的坑
i++;
}
// 从左向右找大于或等于x的数来填s[j]
while(i < j && s[i] < x)
i++;
if(i < j)
{
s[j] = s[i]; //将s[i]填到s[j]中,s[i]就形成了一个新的坑
j--;
}
}
//退出时,i等于j。将x填到这个坑中。
s[i] = x;//此时基准元素被放到正确的位置上
return i;//返回基准元素的位置
//下一次在排序的时候,排基准元素的左边和右边
//排基准元素的左边,下标就是left = 0 right = i-1
//排基准元素的右边,下标就是left = i+1 right = nlen-1
}
void quick_sort1(int s[], int l, int r)
{
if (l < r)
{
int i = AdjustArray(s, l, r);//先成挖坑填数法调整s[]
quick_sort1(s, l, i - 1); // 递归调用
quick_sort1(s, i + 1, r);
}
}
//快速排序
void quick_sort(int s[], int l, int r)
{
if (l < r)
{
//Swap(s[l], s[(l + r) / 2]); //将中间的这个数和第一个数交换 参见注1
int i = l, j = r, x = s[l];
while (i < j)
{
while(i < j && s[j] >= x) // 从右向左找第一个小于x的数
j--;
if(i < j)
s[i++] = s[j];
while(i < j && s[i] < x) // 从左向右找第一个大于等于x的数
i++;
if(i < j)
s[j--] = s[i];
}
s[i] = x;
quick_sort(s, l, i - 1); // 递归调用
quick_sort(s, i + 1, r);
}
}
- 易错点:
1.基准元素的位置被记录下来了,可以理解为这个下标位置是个坑,可以填写其他的数
2.求基准元素的函数中,第二个while循环中,if语句中表达的是基准元素的左边/右边的待排元素就只剩余一个的情况,应该先把基准元素放到这个坑中,再移动下标!! - 性能分析:
1.空间效率:最好O(log2的n方) 最坏O(n) 平均O(log2的n方)
时间效率:最好O(nlog2的n方) 最坏O(n平方) 平均O(nlog2的n方)
2.快排是内部排序中平均性能最优的算法
3.稳定性:不稳定性(输入数据次序越乱,排序的速度越快)
(1)不适用于对原有序或基本有序的数据进行排序
(2)基准元素的选取直接影响时间性能
选择排序:
- 核心思想:遍历数组,每次找到最小的放到对应位置
- 分析步骤:
1.首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。
2.再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
3.重复第二步,直到所有元素均排序完毕。
void swap(int* a, int* b)
{
int temp = *a;
*a = *b;
*b = temp;
}
void select_sort(int arr[], int nlen)
{
for (int i = 0; i < nlen - 1; i++)//数组是从下标0开始的
{
int min = i;//min是数组的下标
//遍历i之后的元素,看看是否有比arr[i]小的,如果有就交换
for (int j = i + 1; j < nlen; j++)
{
if (arr[min] > arr[j])
{
min = j;//赋值语句,记录最小值的下标
}
}
//交换
swap(&arr[min], &arr[i]);
}
}
- 易错点:
1.swap函数注意参数的传递方式:地址传递(值传递,形参的修改不会影响实参)
2.注意swap函数的位置是在第二个for循环的外边:遍历数组找到最小的值才会交换一次 - 性能分析:
1.时间复杂度:O(n的方)
2.使用:数据规模越小越好
3.好处:不占用额外的空间
1万+

被折叠的 条评论
为什么被折叠?



