排序和查找的基础知识

今天我们学习排序和查找

排序

一、排序的概念

所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作

二、今天所要学的排序

冒泡排序、选择排序、直接插入排序、希尔排序、快速排序

稳定的排序:冒泡排序 直接插入排序

不稳定的排序:选择排序 希尔排序 快速排序

三、排序的思想、代码和示意图 

(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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值