软件设计师 第三章 数据结构(下)

这里写目录标题

  • 1.查找
    • 1.1顺序查找
    • 1.2折半查找
    • 1.3哈希表
  • 2.顶堆
  • 3.排序
    • 3.1直接插入排序
    • 3.2希尔排序
    • 3.3计数排序
    • 3.4简单选择排序
    • 3.5堆排序
    • 3.6冒泡排序
    • 3.7快速排序(分治,归位)
    • 3.8归并排序

1.查找

查找表:同一类型的数据元素构成的集合

静态查找表:数据元素是否存在及其属性
有顺序查找,折半(二分)查找,分块查找

动态查找表:插入和删除数据元素
有二叉排序树,平衡二叉树,B_树,哈希表

关键字:数据元素的某个数据项的值
主关键字(唯一),次关键字(多个)

1.1顺序查找

适用于顺序查找和链式查找,不需要有序

平均查找长度:ASL = (n + 1) / 2

1.2折半查找

适用于顺序存储,递增排序

n < mid,右边
n > mid,左边
n = mid,return 下标

最多比较⌊log₂n」+ 1

1.3哈希表

哈希表H,两个关键字K₁,K₂
K₁ ≠ K₂但H(K₁) = H(K₂)称为冲突

同义词:H(6) = 1,H(8) = 1

哈希函数构造
出留取余法:H(key) = key % m = 地址
一共有n个元素,m一般取接近n但≯n的质数

解决冲突
1.开放地址法
线性探测法:(结果+i)%m,i表示冲突的次数
二次探测法:(结果+i)%m,
i是1²,-(1)²,2²,-(2)²,3²,-(3)²…

2.链地址法:
在这里插入图片描述
哈希表查找
与哈希函数,处理冲突的方法,哈希表的装填因子有关

装填因子=表中装填的记录数/哈希表的长度
装填因子越小,发生冲突的可能性越小,反之越大

2.顶堆

在这里插入图片描述

3.排序

排序算法平均最坏最好空间稳定性
直接插入排序O(n²)O(n²)O(n)O(1)稳定
冒泡排序O(n²)O(n²)O(n)O(1)稳定
希尔排序O(n^1.3)O(n²)O(n)O(1)不稳定
简单选择排序O(n²)O(n²)O(n²)O(1)不稳定
堆排序O(nlog₂n)O(nlog₂n)O(nlog₂n)O(1)不稳定
快速排序O(nlog₂n)O(n²)O(nlog₂n)O(log₂n)不稳定
归并排序O(nlog₂n)O(nlog₂n)O(nlog₂n)O(n)稳定

3.1直接插入排序

基本有序适用于直接插入排序

从第二个元素开始与前比较
插入的数>=放后面
插入的数<放前面

局部有序,每次不能确定最终位置

3.2希尔排序

将整个序列分成若干子序列,分别进行直接插入排序
在这里插入图片描述
最后一趟,整个为一组进行直接插入排序

3.3计数排序

只有1-9
先记下每个数字有几次,在从小到大排序

3.4简单选择排序

可以归位(却定元素的最终位置)

int selection(int[] a,int n){
  for(int i = 0;i < n - 1;i++){
    //遍历数组
    int min = i;//假设第一个数是最小的
    for(int j = i + 1;j < n;j++){
      //从第二个数开始,与第一个数比较
      if(a[j] < a[min]){
        min = j;
      }
    }
    if(min != i){
      int temp = a[i];
      a[i] = a[min];
      a[min] = temp;
    }
  }
}

进行n-1 趟排序

3.5堆排序

将元素化成大顶堆,交换第一个和最后一个数,可以确定最大的数的位置,再构成大顶堆再交换,直到完成排序

大顶堆排完后是递增序列
小顶堆排完后是递减序列

3.6冒泡排序

/*
1.一共有n个数
2.进行了n-1轮排序,可以看成外层循环
3.每一轮可以确定一个数的位置
4.如果前>后就交换位置(从小到大)
5.每轮比较n-i-1次*/
public class 冒泡排序 {  
  public static void main(String[] args) {    
    int[] arr = {23,25,15,8,96,108};    
    int temp = 0;    
    for(int i = 0;i < arr.length-1;i++){        
      for(int j = 0;j < arr.length - i - 1;j++){            
        if(arr[j] > arr[j + 1]){                
          temp = arr[j + 1];                
          arr[j + 1] = arr[j];                
          arr[j] = temp;            
        }        
      }    
    }    
    for(int i = 0;i < arr.length;i++) {        
      System.out.println(arr[i]);    
    }  
  }
}

3.7快速排序(分治,归位)

/*
设置两个变量i,j
它们的初值分别指向第一个记录和最后一个记录
设置一个pivot,通常是第一个记录
先从后往前找第一个 < pivot的记录
a[i] = a[j]
从前往后找第一个 > pivot的记录
a[j] = a[i]
重复,直至i = j
*/
void quick_sort(int[] a,int l,int r){
  if(l >= r) return;
  
  int i = l,j = r,pivot = a[l];
  while(i < j){
    while(i < j && j >= pivot)j--;
    a[i] = a[j];
    while(i < j && i <= pivot)i++;
    a[j] = a[i];
  }
  a[i] = pivot;//重新开始
  
  quick_sort(a,l,i - 1);
  quick_sort(a,i + 1,r)
}

3.8归并排序

将一组数据/2ˣ,直到结果为1,然后进行合并

void merge_sort(int[] a,int l,int r){
  if(r >= l) return;
  int mid = (l + r) / 2;
  merge_sore(a,l,mid);
  merge_sore(a,mid + 1,r);
  //将一组数据/2ˣ,直到结果为1
  
  int i = l,j = mid + 1,k = 0;
  //k是辅助数组t[]的下标
  while(i <= mid && j <= r){
    if(a[i] <= a[j]){
      t[k++] = a[i++];
    }else{
      t[k++] = a[j++];
    }
  }
  
  while(i <= mid)t[k++] = a[i++];
  while(j <= r)t[k++] = a[j++];

  for(i = l,j = 0;i <= r;i++,j++)a[i] = t[j];
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值