今天我们学习排序和查找
排序
一、排序的概念
所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作
二、今天所要学的排序
冒泡排序、选择排序、直接插入排序、希尔排序、快速排序
稳定的排序:冒泡排序 直接插入排序
不稳定的排序:选择排序 希尔排序 快速排序
三、排序的思想、代码和示意图
(1)、冒泡排序
冒泡排序的思想:两数比较,将最大或者最小元素,放到最后
int i,j,temp; //定义 外层循环变量 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;
}
}
}
冒泡排序的示意图:
(2)、选择排序
选择排序的思想:找最大或者最小的元素 往前放,分成已排序和待排序序列
void selectSort(int arr[] , int len){
int i, j , temp , min;
for(i=0; i<len; i++){
min = i; //min 标记 未排序第一个与元素位置
for(j = i+1; j<len; j++){ //找比 min 位置还小的元素
if(arr[j]>arr[min]){
min = j;
}
}
if(min != i){
temp =arr[min];
arr[min] = arr[i];
arr[i] = temp;
}
}
}
选择排序的示意图:
注意:选择排序不稳定,平均比较次数n(n-1)/2
(3) 直接插入排序
直接插入排序的思想:从后向前进行 查找 确定的位置,并插入元素
void insertSort(int arr[] , int len){
int i ,j ,temp;
for(i=1; i<len; i++){ //从1开始, 0 位置当成有序
temp = arr[i]; //temp 记录未排序第一个
for(j=i-1; j>=0 && arr[j] > temp; j--){
arr[j+1] = arr[j]; //元素后移,腾位置给插入元素
}
arr[j+1] = temp; //插入 比较的 后一位
}
}
直接插入排序的示意图
注意:直接插入排序, 是在有序基础上, 速度最快且稳定的 排序方法
(4)希尔排序
希尔排序的思想:按照 步长 进行分组,然后每一组的 第 几个 元素 进行排序
//dk 是增量 步长
void shellInsert(int arr[] , int len , int dk){
int i , j ,temp; //i 循环变量 j 记录前边组的位置 temp 临时变量
for(i = dk ; i < len ; i++){
//判断每组的 第几个元素大小
if(arr[i] < arr[i-dk]){ //后边组 小于 前边组
temp = arr[i];
j = i-dk;
for(;j>=0 && temp < arr[j]; j=j-dk){
//前边的值 给到 后边
arr[j+dk] = arr[i];
}
arr[j+dk] = temp;
}
}
}
希尔排序的示意图
(5)快速排序
快速排序的思想:基准值,i 从前向后找,比基准值大的元素 j 从后向前找,找比基准值小的元素,最后,结束的条件是i=j 此时将 基准值放到这个位置
int getPivot(int arr[] , int low , int high){
int pivot = arr[low];
while(low < high){ //i < j 的时候
//j 从后向前找,比基准值 小的元素
while(low < high && arr[high] >= pivot){
high--;
}
//找到了 比基准值小的元素 将元素 给到 i 的位置
arr[low] = arr[high];
//i 从前向后找 , 比基准值 大的元素
while(low < high && arr[low] <= pivot){
low++;
}
//找到了 比基准值大的元素 将元素 给到 i 的位置
arr[high] = arr[low];
}
//结束条件 i = j 找到了基准值的位置
arr[low] = pivot;
//返回基准值位置
return low;
}
void quickSort(int arr[] , int low , int high){
if(low < high){
//基准值位置的变量
int pivot = getPivot(arr,low,high);
//递归 对 基准值位置 左边进行 快速排序
quickSort(arr,low,pivot-1);
//递归 对 基准值位置 右边进行 快速排序
quickSort(arr, pivot+1 ,high);
}
}
快速排序的示意图
查找
一、查找的概念
查询某个关键字是否在(数据元素集合)表中的过程
二、查找的代码和示意图
(1)、顺序查找
顺序查找:遍历数组,拿元素依次比较,相同返回 下标,找不到,返回 -1
//arr 数组 len 数组长度 value 要查找的值
int linearSearch(int arr[] , int len , int value){
int i;
for(i=0 ; i<len ; i++){
if(arr[i] == value){
return i;
}
}
return -1; //找不到
}
顺序查找的示意图
(2)二分查找
非递归
//arr 数组 , low 左边值 , high 右边值 , key 要查找的关键字
int binarySearch(int arr[] , int low , int high , int key){
int mid; //中间值
while(low <= high){
mid = (low + high)/2; //找中间位置
if(key == arr[mid]){
return mid; //返回下标
}else if(key >= arr[mid]){
low = mid + 1;
}else{
high = mid - 1;
}
}
//没有找到关键字
return -1;
}
递归
int binarySearch(int arr[] , int high , int low , int key){
int mid; //中间下标
if(low <= high){
mid = (low + high)/2;
if(key == arr[mid]){
return mid; //递归出口
}else if(key > arr[mid]){
return binarySearch(arr , mid + 1 , high , key);
}else{
return binarySearch(arr , low , mid - 1 , key);
}
}
return -1;
}