基础3 算法

基础3 算法

数据结构与算法

1. 链表与数组。

2. 队列和栈,出栈与入栈。

3. 链表的删除、插入、反向。

4. 字符串操作。

5. Hash表的hash函数,冲突解决方法有哪些。

6. 各种排序:冒泡、选择、插入、希尔、归并、快排、堆排、桶排、基数的原理、平均时间复杂度、最坏时间复杂度、空间复杂度、是否稳定。

7. 快排的partition函数与归并的Merge函数。

8. 对冒泡与快排的改进。

9. 二分查找,与变种二分查找。

10. 二叉树、B+树、AVL树、红黑树、哈夫曼树。

11. 二叉树的前中后续遍历:递归与非递归写法,层序遍历算法。

12. 图的BFS与DFS算法,最小生成树prim算法与最短路径Dijkstra算法。

13. KMP算法。

14. 排列组合问题。

15. 动态规划、贪心算法、分治算法。(一般不会问到)

16. 大数据处理:类似10亿条数据找出最大的1000个数.........等等

算法的话其实是个重点,因为最后都是要你写代码,所以算法还是需要花不少时间准备,这里有太多算法题,写不全,我的建议是没事多在OJ上刷刷题(牛客网、leetcode等),剑指offer上的算法要能理解并自己写出来,编程之美也推荐看一看。

推荐书籍:《大话数据结构》《剑指offer》《编程之美》

常用数据结构

  数组 Array 将具有相同类型得若干变量有序的组织在一起的集合

  栈 Stack 特殊线性表 只能在表的一个固定端进行数据结点的插入和删除操作 后进先出

  队列 Queue 特殊线性表 只能在表的一端进行插入操作 另一端进行删除操作 先进先出

  链表 Linked List 一种数据元素安装链式存储结构进行存储的数据结构

  树 Tree 非线性结构 包含n个结点的有穷集合K 图 Graph

  堆 Heap 特殊的树型数据结构 二叉堆 根结点的值是所有结点中最小或最大的

  散列表 Hash 源于散列函数 在结构中存在关键字和T相等的记录 则必定在F(T)的存储位置可以找到该记录

冒泡排序 BubbleSort

思路 相邻元素比较 两两交换 一轮排序结束 最大的元素沉底

public class BubbleSort {
  
  static final int SIZE=10;
  
  public static void main(String[] args) {

    int[] testArray=new int[SIZE];
    
    //初始化数组 值为随机值
    for(int i=0;i<SIZE;i++){
      testArray[i]=(int)(100+Math.random()*(100+1));
    }

    System.out.print("排序前");
    printArray(testArray);
    
    bubbleSort(testArray);
    
    System.out.print("排序后");
    printArray(testArray);
    
  }
  
  public static void bubbleSort(int[] a) {
    int temp;
    for (int i = 1; i < a.length; i++) {
             //将相邻两个数进行比较,较大的数往后冒泡
           for (int j = 0; j < a.length - i; j++) {
             if (a[j] > a[j + 1]) {
               temp=a[j];
               a[j]=a[j+1];
               a[j+1]=temp;
             }
           }
           System.out.print("第"+i+"步排序结果:");
           printArray(a);
    }
  }
  
  //打印数组元素
  public static void printArray(int[] a){
    for (int i = 0; i < a.length; i++) {
      System.out.print(" "+a[i]);
    }
    System.out.print("\n"); 
  }
  
}

输出结果

排序前 162 161 117 139 196 107 173 179 132 160
第1步排序结果: 161 117 139 162 107 173 179 132 160 196
第2步排序结果: 117 139 161 107 162 173 132 160 179 196
第3步排序结果: 117 139 107 161 162 132 160 173 179 196
第4步排序结果: 117 107 139 161 132 160 162 173 179 196
第5步排序结果: 107 117 139 132 160 161 162 173 179 196
第6步排序结果: 107 117 132 139 160 161 162 173 179 196
第7步排序结果: 107 117 132 139 160 161 162 173 179 196
第8步排序结果: 107 117 132 139 160 161 162 173 179 196
第9步排序结果: 107 117 132 139 160 161 162 173 179 196
排序后 107 117 132 139 160 161 162 173 179 196

 

选择排序 SelectionSort 

思路 选择第1个位置 两两比较元素 让第1一个位置上的元素最小 依次。。。

public class SelectionSort {

  static final int SIZE = 10;

  public static void main(String[] args) {

    int[] testArray = new int[SIZE];

    // 初始化数组 值为随机值
    for (int i = 0; i < SIZE; i++) {
      testArray[i] = (int) (100 + Math.random() * (100 + 1));
    }

    System.out.print("排序前");
    printArray(testArray);

    selectSort(testArray);

    System.out.print("排序后");
    printArray(testArray);

  }

  public static void selectSort(int[] a) {
    int index, temp;
    for (int i = 0; i < a.length - 1; i++) {
      index = i;
      for (int j = i + 1; j < a.length; j++) {
        if (a[j] < a[index]) {
          index = j;
        }
      }
      // 第i个元素是处在大小i的位置上 则不交换 否则交换两个数
      if (index != i) {
        temp = a[i];
        a[i] = a[index];
        a[index] = temp;
      }
      System.out.print("第" + i + "步排序结果:"); // 输出每步排序的结果
      printArray(a);
    }

  }

  // 打印数组元素
  public static void printArray(int[] a) {
    for (int i = 0; i < a.length; i++) {
      System.out.print(" " + a[i]);
    }
    System.out.print("\n");
  }

}
排序前 188 180 166 142 197 196 105 120 184 125
第0步排序结果: 105 180 166 142 197 196 188 120 184 125
第1步排序结果: 105 120 166 142 197 196 188 180 184 125
第2步排序结果: 105 120 125 142 197 196 188 180 184 166
第3步排序结果: 105 120 125 142 197 196 188 180 184 166
第4步排序结果: 105 120 125 142 166 196 188 180 184 197
第5步排序结果: 105 120 125 142 166 180 188 196 184 197
第6步排序结果: 105 120 125 142 166 180 184 196 188 197
第7步排序结果: 105 120 125 142 166 180 184 188 196 197
第8步排序结果: 105 120 125 142 166 180 184 188 196 197
排序后 105 120 125 142 166 180 184 188 196 197

 

插入排序 InsertionSort

思路 将数组前两个元素排好 将第3个元素插入到前两个元素中 依次。。。

public class InsertionSort {

  static final int SIZE = 10;

  public static void main(String[] args) {

    int[] testArray = new int[SIZE];

    // 初始化数组 值为随机值
    for (int i = 0; i < SIZE; i++) {
      testArray[i] = (int) (100 + Math.random() * (100 + 1));
    }

    System.out.print("排序前");
    printArray(testArray);

    selectSort(testArray);

    System.out.print("排序后");
    printArray(testArray);

  }

  //插入排序
  public static void selectSort(int[] a) {
    int i, j, t;
    for (i = 1; i < a.length; i++) {
      t = a[i]; //需要插入的元素
      j = i - 1; //需要插入的位置
      while (j >= 0 && t < a[j]) {
        a[j + 1] = a[j];
        j--;
      }
      a[j + 1] = t;

      System.out.print("第" + i + "步排序结果:"); // 输出每步排序的结果
      printArray(a);
    }
  }

  // 打印数组元素
  public static void printArray(int[] a) {
    for (int i = 0; i < a.length; i++) {
      System.out.print(" " + a[i]);
    }
    System.out.print("\n");
  }

}
排序前 111 195 143 198 186 192 137 170 111 141
第1步排序结果: 111 195 143 198 186 192 137 170 111 141
第2步排序结果: 111 143 195 198 186 192 137 170 111 141
第3步排序结果: 111 143 195 198 186 192 137 170 111 141
第4步排序结果: 111 143 186 195 198 192 137 170 111 141
第5步排序结果: 111 143 186 192 195 198 137 170 111 141
第6步排序结果: 111 137 143 186 192 195 198 170 111 141
第7步排序结果: 111 137 143 170 186 192 195 198 111 141
第8步排序结果: 111 111 137 143 170 186 192 195 198 141
第9步排序结果: 111 111 137 141 143 170 186 192 195 198
排序后 111 111 137 141 143 170 186 192 195 198

 

shell排序 ShellSort

思路 将n个元素的数组分成n/2个数字序列 第1个数据和第n/2+1个数据为一对 两两比较交换 再变成n/4个序列。。。

public class ShellSort {

  static final int SIZE = 10;

  public static void main(String[] args) {

    int[] testArray = new int[SIZE];

    // 初始化数组 值为随机值
    for (int i = 0; i < SIZE; i++) {
      testArray[i] = (int) (100 + Math.random() * (100 + 1));
    }

    System.out.print("排序前");
    printArray(testArray);

    shellSort(testArray);

    System.out.print("排序后");
    printArray(testArray);

  }

  public static void shellSort(int[] a) // Shell排序
  {
    int i, j;
    int r, temp;
    int x = 0;

    for (r = a.length / 2; r >= 1; r /= 2) // 划组排序
    {
      for (i = r; i < a.length; i++) {
        temp = a[i];
        j = i - r;
        while (j >= 0 && temp < a[j]) {
          a[j + r] = a[j];
          j -= r;
        }
        a[j + r] = temp;
      }

      x++;
      System.out.print("第" + x + "步排序结果:"); // 输出每步排序的结果
      printArray(a);
    }
  }

  // 打印数组元素
  public static void printArray(int[] a) {
    for (int i = 0; i < a.length; i++) {
      System.out.print(" " + a[i]);
    }
    System.out.print("\n");
  }

}
排序前 169 128 175 135 191 118 181 128 184 192
第1步排序结果: 118 128 128 135 191 169 181 175 184 192
第2步排序结果: 118 128 128 135 181 169 184 175 191 192
第3步排序结果: 118 128 128 135 169 175 181 184 191 192
排序后 118 128 128 135 169 175 181 184 191 192

 

快速排序 QuickSort

思路 设定一个分界值 将大于等于分界值得数据集中到数组右边 小于的到左边 递归。。。

public class QuickSort {

  static final int SIZE = 10;

  public static void main(String[] args) {

    int[] testArray = new int[SIZE];

    // 初始化数组 值为随机值
    for (int i = 0; i < SIZE; i++) {
      testArray[i] = (int) (100 + Math.random() * (100 + 1));
    }

    System.out.print("排序前");
    printArray(testArray);

    quickSort(testArray, 0, SIZE - 1);

    System.out.print("排序后");
    printArray(testArray);

  }

  // 快速排序算法
  public static void quickSort(int[] arr, int left, int right) {
    int f, t;
    int rtemp, ltemp;

    ltemp = left;
    rtemp = right;
    f = arr[(left + right) / 2]; // 分界值
    while (ltemp < rtemp) {
      while (arr[ltemp] < f) {
        ++ltemp;
      }
      while (arr[rtemp] > f) {
        --rtemp;
      }
      if (ltemp <= rtemp) {
        t = arr[ltemp];
        arr[ltemp] = arr[rtemp];
        arr[rtemp] = t;
        --rtemp;
        ++ltemp;
      }
    }
    if (ltemp == rtemp) {
      ltemp++;
    }

    if (left < rtemp) {
      quickSort(arr, left, ltemp - 1); // 递归调用
    }
    if (ltemp < right) {
      quickSort(arr, rtemp + 1, right); // 递归调用
    }
  }

  // 打印数组元素
  public static void printArray(int[] a) {
    for (int i = 0; i < a.length; i++) {
      System.out.print(" " + a[i]);
    }
    System.out.print("\n");
  }

}
排序前 158 184 117 192 136 113 116 164 133 123
排序后 113 116 117 123 133 136 158 164 184 192

 

堆排序 HeapSort

思路 基于堆结构

public class HeapSort {

  static final int SIZE = 10;

  public static void main(String[] args) {

    int[] testArray = new int[SIZE];

    // 初始化数组 值为随机值
    for (int i = 0; i < SIZE; i++) {
      testArray[i] = (int) (100 + Math.random() * (100 + 1));
    }

    System.out.print("排序前");
    printArray(testArray);

    heapSort(testArray, SIZE);

    System.out.print("排序后");
    printArray(testArray);

  }

  // 堆排序
  public static void heapSort(int a[], int n) {
    int i, j, h, k;
    int t;

    for (i = n / 2 - 1; i >= 0; i--) // 将a[0,n-1]建成大根堆
    {
      while (2 * i + 1 < n) // 第i个结点有右子树
      {
        j = 2 * i + 1;
        if ((j + 1) < n) {
          if (a[j] < a[j + 1]) // 右左子树小于右子树,则需要比较右子树
            j++; // 序号增加1,指向右子树
        }
        if (a[i] < a[j]) // 比较i与j为序号的数据
        {
          t = a[i]; // 交换数据
          a[i] = a[j];
          a[j] = t;
          i = j; // 堆被破坏,需要重新调整
        } else // 比较左右子结点均大则堆未破坏,不再需要调整
        {
          break;
        }
      }
    }
    // 输出构成的堆
    System.out.print("原数据构成的堆:");
    for (h = 0; h < n; h++) {
      System.out.print(" " + a[h]); // 输出
    }
    System.out.print("\n");

    for (i = n - 1; i > 0; i--) {
      t = a[0]; // 与第i个记录交换
      a[0] = a[i];
      a[i] = t;
      k = 0;
      while (2 * k + 1 < i) // 第i个结点有右子树
      {
        j = 2 * k + 1;
        if ((j + 1) < i) {
          if (a[j] < a[j + 1]) // 右左子树小于右子树,则需要比较右子树
          {
            j++; // 序号增加1,指向右子树
          }
        }
        if (a[k] < a[j]) // 比较i与j为序号的数据
        {
          t = a[k]; // 交换数据
          a[k] = a[j];
          a[j] = t;
          k = j; // 堆被破坏,需要重新调整
        } else // 比较左右子结点均大则堆未破坏,不再需要调整
        {
          break;
        }
      }

      System.out.print("第" + (n - i) + "步排序结果:"); // 输出每步排序的结果
      printArray(a);
    }
  }

  // 打印数组元素
  public static void printArray(int[] a) {
    for (int i = 0; i < a.length; i++) {
      System.out.print(" " + a[i]);
    }
    System.out.print("\n");
  }
}
排序前 172 146 123 150 164 159 106 189 150 195
原数据构成的堆: 195 189 159 172 164 123 106 150 150 146
第1步排序结果: 189 172 159 150 164 123 106 146 150 195
第2步排序结果: 172 164 159 150 150 123 106 146 189 195
第3步排序结果: 164 150 159 146 150 123 106 172 189 195
第4步排序结果: 159 150 123 146 150 106 164 172 189 195
第5步排序结果: 150 150 123 146 106 159 164 172 189 195
第6步排序结果: 150 146 123 106 150 159 164 172 189 195
第7步排序结果: 146 106 123 150 150 159 164 172 189 195
第8步排序结果: 123 106 146 150 150 159 164 172 189 195
第9步排序结果: 106 123 146 150 150 159 164 172 189 195
排序后 106 123 146 150 150 159 164 172 189 195

 合并排序 MergeSort

public class MergeSort {

  static final int SIZE = 15;

  static void mergeOne(int a[], int b[], int n, int len) // 完成一遍合并的函数
  {
    int i, j, k, s, e;

    s = 0;
    while (s + len < n) {
      e = s + 2 * len - 1;
      if (e >= n) // 最后一段可能少于len个结点
      {
        e = n - 1;
      }
      // 相邻有序段合并
      k = s;
      i = s;
      j = s + len;
      while (i < s + len && j <= e) // 如果两个有序表都未结束时,循环比较
      {
        if (a[i] <= a[j]) // 如果较小的元素复制到数组b中
        {
          b[k++] = a[i++];
        } else {
          b[k++] = a[j++];
        }
      }
      while (i < s + len) // 未合并的部分复制到数组b中
      {
        b[k++] = a[i++];
      }
      while (j <= e) {
        b[k++] = a[j++]; // 未合并的部分复制到数组b中
      }

      s = e + 1; // 下一对有序段中左段的开始下标
    }
    if (s < n) // 将剩余的一个有序段从数组A中复制到数组b中
    {
      for (; s < n; s++) {
        b[s] = a[s];
      }
    }
  }

  static void mergeSort(int a[], int n) // 合并排序
  {
    int h, count, len, f;

    count = 0; // 排序步骤
    len = 1; // 有序序列的长度
    f = 0; // 变量f作标志
    int[] p = new int[n];
    while (len < n) {
      if (f == 1) // 交替在A和P之间合并
      {
        mergeOne(p, a, n, len); // p合并到a
      } else {
        mergeOne(a, p, n, len); // a合并到p
      }
      len = len * 2; // 增加有序序列长度
      f = 1 - f; // 使f值在0和1之间切换

      count++;
      System.out.printf("第" + count + "步排序结果:"); // 输出每步排序的结果
      for (h = 0; h < SIZE; h++) {
        System.out.printf(" " + a[h]); // 输出
      }
      System.out.print("\n");

    }
    if (f == 1) // 如果进行了排序
    {
      for (h = 0; h < n; h++) // 将内存p中的数据复制回数组a
      {
        a[h] = p[h];
      }
    }
  }

  public static void main(String[] args) {
    int[] testArray = new int[SIZE];

    for (int i = 0; i < SIZE; i++) {
      testArray[i] = (int) (100 + Math.random() * (100 + 1)); // 初始化数组
    }

    System.out.print("排序前的数组为:\n"); // 输出排序前的数组
    printArray(testArray);

    mergeSort(testArray, SIZE); // 排序操作

    System.out.print("排序后的数组为:\n");
    printArray(testArray);

  }

  // 打印数组元素
  public static void printArray(int[] a) {
    for (int i = 0; i < a.length; i++) {
      System.out.print(" " + a[i]);
    }
    System.out.print("\n");
  }

}
排序前的数组为:
 180 192 146 174 156 108 116 136 121 142 167 116 159 156 186
第1步排序结果: 180 192 146 174 156 108 116 136 121 142 167 116 159 156 186
第2步排序结果: 146 174 180 192 108 116 136 156 116 121 142 167 156 159 186
第3步排序结果: 146 174 180 192 108 116 136 156 116 121 142 167 156 159 186
第4步排序结果: 108 116 116 121 136 142 146 156 156 159 167 174 180 186 192
排序后的数组为:
 108 116 116 121 136 142 146 156 156 159 167 174 180 186 192

 

你可能感兴趣的:(基础3 算法)