数据结构笔记



排序:


1、冒泡排序


2、选择排序:冒泡排序的改进型,不用移动那么多节点;
选择排序:选择其中最小的值
找个一关键字,第一次循环,第一个和关键字比较,如果第一个比关键字小,则将值赋予关键字,并记录下索引,
第二个和关键字比较,如果比关键字小,,则将值赋予关键字,并记录下索引,依此类推,第一遍循环完,关键字
即第一个到最后一个中的最小数,放到第一个位置,原来第一个位置的数,放到关键字索引处;
再循环第二个到最后一个,依此类推


3、插入排序:从无序表中取出第一个元素,插入到有序表中,使有序表依然有序;
直接插入排序
从无序表中取出一个元素把它插入到一个有序表的合适位置,使有序表依然有序。
将要排序的数组分为两部分,第一部分只包含一个数,第二部分包含余下的数,
取第二部分的第一个数和第一部分的数比较并排序,
接着取第二部分的一个数,和第一部分的两个数从小到大比较,排序,
如此递归下去

4、希尔排序:以增量递减,分成增量个组,组内直接插入排序,直到增量递减为1;


5、快速排序:收尾移动比较;
int[] nums = new int[size];
 i=0, j=size-1, key=nums[0]; 
 从j开始,往前看,找到第一个小于key的数,交换位置,j--;
 从i开始,往后看,找到第一个大于key的数,交换位置,i++;
 直到i==j;
 
6、基数排序:个位排序,十位排序,...


7、堆排序:二叉树排序;
树中任一非叶子节点的关键字均不大于(或均不小于)其左右孩子节点的关键字


8、归并排序:针对两个有序集合排序;
建立在归并操作的基础之上,即:
 新建一个空间sm,大小为s1、s2之和
 两个有序的集合S1、S2,用两个指针平p1、p2分别指向S1、S2的起始位置,
 比较,如果p1小于p2,则将p1指的数放入sm,p1向前走一个点,再与p2比较
 重复操作
 


********************************************************************************


查找:


1、无序表查找:顺序查找;
2、有序表查找:折半(二分)查找、插入查找、斐波那契查找、二叉排序树查找、哈希表(散列表)查找;


1、折半查找
int[] nums
 取min=0、max=nums.length、mid=(max-min)/2、查找目标key
 如果key<nums[mid],则max=mid-1,如果key>nums[mid],则min=mid+1,
 递归下去;
 插值查找、斐波那契查找都是对折半查找的优化,都是建立在缩小mid范围的基础之上;
  
2、插入查找
插值查找 —— 折半查找 + 插值算法,有序表查找
插值算法:mid=(key-a[min])/(a[max]-a[min])*(max-min)

3、斐波那契查找
斐波那契查找:折半查找 + 斐波那契数列,有序表查找
int[] nums:需查找数列
int[] fnums:斐波那契数列
nums.length=<fnums[k]-1 && nums.length>fnums[k-1]-1;
mid = min + fnums[k-1]-1

4、二叉排序树查找
如果查找值小于根节点,遍历左子树,否则遍历右子树;

5、哈希表查找


********************************************************************************




字符串:KMP匹配算法;


哈弗曼编码:最短的编码格式;
5、4、3、2、1 ——> 5、4、3、3 ——> 5、4、6 ——> 9、6,取两个最小的合并为一,放到集合中,继续取两个最小的合并为一,小的放左,大的放右;


图的结构:
1、邻接矩阵;2、邻接表;3、十字链表;4、邻接多重表;5、边集数组;


1、最小生成树:各个城市铺电缆,用最短的电缆连接所有的城市;
  克鲁斯卡尔算法:将图中边按其权值由小到大的次序顺序选取,若选边后不形成回路,则保留作为一条边,
    若形成回路则除去.依次选够(n-1)条边,即得最小生成树.(n为顶点数);
  普里姆算法:随意取一个点,取关联点的最小的边;


2、最短路径:坐地铁从A地到B地,怎么选最短路径;


  迪杰斯特拉算法:单个源点到所有顶点的最短路径;
  求A点到Z点的距离;
    1)列出A点到所有点的距离,求出最短距离D(A,E);
    2)列出A点到所有点X的距离(不包含E点),求出次短距离D(A,G);
      次短离或者是D(A,X),或者是D(A,E)+D(E,X),二者选短者;
    3)列出A点到所有点X的距离(不包含E、G点),求出次短距离D(A,W);
      次短离或者是D(A,W),或者是D(A,G)+D(G,X),G点即上次求出的次短距离,二者选短者;
    4)如此循环,即可得出A点到所有点的最端距离;


  弗洛伊德算法:
    1)让所有边上加入中间顶点1,取A[i][j]与A[i][1]+A[1][j]中较小的值作A[i][j]的值,完成后得到A(1)矩阵;
    2)让所有边上加入中间顶点2,取A[i][j]与A[i][2]+A[2][j]中较小的值,完成后得到A(2)…,其中,A[i][2]取A(1)矩阵得出的值!
      如此进行下去,当第n步完成后,得到A(n),A(n)即为我们所求结果,A(n)[i][j]表示顶点i到顶点j的最短距离。


3、拓扑排序:从图中选择一个入度为0的顶点输出,然后删去此顶点,并删除以此顶点为尾的弧,继续重复此步骤,直到输出
  全部顶点或图中不存在入度为0的顶点为止。如果没输出全部顶点,说明存在回路;拓扑排序保证施工的步骤是顺序执行;


4、关键路径
  最早发生时间 = 最晚发生时间
  最早发生时间:取最长路径;
  最晚发生时间:汇聚点的最长路径 - 多出的路径;


5、查找
  顺序查找
  有序表查找:
  折半查找
  插值查找:mid = low + ((key-a[low])/(a[high]-a[low]))*(high-low)
  斐波那契查找


6、排序
  冒泡排序
  简单选择排序:冒泡排序要一直交换,简单排序则记录最大值的下标,一直在改变的是下标,直到比较完,再交换数据;
  直接插入排序:将一个数插入到一个已经排好序的数列中;
  希尔排序:跳跃分组排序;
  堆排序:
  归并排序:
  快速排序:针对有序数列;
  快速排序
  publicint getMiddle(int[] list, int low, int high) {
    int tmp = list[low]; //数组的第一个作为中轴
    while (low < high) {
      while (low < high && list[high] >= tmp) {
        high--;
      }


      list[low] = list[high]; //比中轴小的记录移到低端


      while (low < high && list[low] <= tmp) {
        low++;
      }
      
      list[high] = list[low]; //比中轴大的记录移到高端
    }


    list[low] = tmp; //中轴记录到尾
    
    return low; //返回中轴的位置
  }


  public void _quickSort(int[] list, int low, int high) {  
    if (low < high) {  
      int middle = getMiddle(list, low, high); //将list数组进行一分为二  
      _quickSort(list, low, middle - 1); //对低字表进行递归排序  
      _quickSort(list, middle + 1, high); //对高字表进行递归排序  
    }
  }


  折半查找
  public static int splitHalf(int[] arrayData,int searchData,int start,int end){
    int index = (start + end)/2;
    int data = arrayData[index];
    
    if(data == searchData){
      return index;
    }else{
      if(data < searchData){
        return splitHalf(arrayData,searchData,index+1,end);
      }else{
        return splitHalf(arrayData,searchData,start,index-1);
      }
    }
  }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值