八大排序算法

https://juejin.im/post/5c355875518825262058198b

 

八大排序算法

冒泡排序

public class BubbleSort {
    // 冒泡排序,a是数组,n表示数组大小
    public static void bubbleSort(int[] a, int n) {
        if (n <= 1) return;
        for (int i = 0; i < n; ++i) {
            // 提前退出标志位
            boolean flag = false;
            for (int j = 0; j < n - i - 1; ++j) {
                if (a[j] > a[j+1]) { // 交换
                    int tmp = a[j];
                    a[j] = a[j+1];
                    a[j+1] = tmp;
                    // 此次冒泡有数据交换
                    flag = true;
                }
            }
            if (!flag) break;  // 没有数据交换,提前退出
        }
    }
}
复制代码

选择排序

public class SelectionSort {
    // 选择排序,a表示数组,n表示数组大小
    public static void selectionSort(int[] a, int n) {
        if (n <= 1) return;
        for (int i = 0; i < n - 1; ++i) {
            // 查找最小值
            int minIndex = i;
            for (int j = i + 1; j < n; ++j) {
                if (a[j] < a[minIndex]) {
                    minIndex = j;
                }
            }
            // 交换
            int tmp = a[i];
            a[i] = a[minIndex];
            a[minIndex] = tmp;
        }
    }
}
复制代码

插入排序、希尔排序

public class InsertionSortAdd {

    public static void main(String[] args) {
        int[] array = new int[]{4, 6, 5, 3, 7, 1, 2};
    //    int[] array = Arrays.copyOf(data, data.length);
//        insertSort(array);
        shellSort(array, 7,2);
        shellSort(array, 7,1);
//        insertSort(Arrays.copyOf(data, data.length));
        for (int i = 0; i < array.length; i++) {
            System.out.print(array[i] + " ");
        }
    }
    //插入排序
    public static void insertSort(int[] array, int n) {
        if (n <= 1) return;

        for (int i = 0; i < n; i++) {
            int j = i;
            int target = array[j];

            while (j > 0 && target < array[j - 1]) {
                array[j] = array[j - 1];
                j--;
            }
            array[j] = target;
        }
    }
    
    //shell排序
    public static void shellSort(int[] array, int n, int step) {
        if (n <= 1)return;   
        for (int k = 0; k < step; k++) {
            for (int i = k + step; i < n; i = i + step) {
                int j = i;
                int target = array[j];
                while (j > step -1 && target < array[j - step]) {
                    array[j] = array[j - step];
                    j = j - step;
                }
                array[j] = target;
            }
        }
    }
}
复制代码

归并排序

public class MergeSort {

  // 归并排序算法, a是数组,n表示数组大小
  public static void mergeSort(int[] a, int n) {
    mergeSortInternally(a, 0, n-1);
  }

  // 递归调用函数
  private static void mergeSortInternally(int[] a, int p, int r) {
    // 递归终止条件
    if (p >= r) return;

    // 取p到r之间的中间位置q,防止(p+r)的和超过int类型最大值
    int q = p + (r - p)/2;
    // 分治递归
    mergeSortInternally(a, p, q);
    mergeSortInternally(a, q+1, r);

    // 将A[p...q]和A[q+1...r]合并为A[p...r]
    merge(a, p, q, r);
  }

  private static void merge(int[] a, int p, int q, int r) {
    int i = p;
    int j = q+1;
    int k = 0; // 初始化变量i, j, k
    int[] tmp = new int[r-p+1]; // 申请一个大小跟a[p...r]一样的临时数组
    while (i<=q && j<=r) {
      if (a[i] <= a[j]) {
        tmp[k++] = a[i++]; // i++等于i:=i+1
      } else {
        tmp[k++] = a[j++];
      }
    }
    // 判断哪个子数组中有剩余的数据
    int start = i;
    int end = q;
    if (j <= r) {
      start = j;
      end = r;
    }
    // 将剩余的数据拷贝到临时数组tmp
    while (start <= end) {
      tmp[k++] = a[start++];
    }
    // 将tmp中的数组拷贝回a[p...r]
    for (i = 0; i <= r-p; ++i) {
      a[p+i] = tmp[i];
    }
  }
}
复制代码

快速排序、找出第K大的值

public class QuickSort {
  // 快速排序,a是数组,n表示数组的大小
  public static void quickSort(int[] a, int n) {
    quickSortInternally(a, 0, n-1);
  }

  // 快速排序递归函数,p,r为下标
  private static void quickSortInternally(int[] a, int p, int r) {
    if (p >= r) return;

    int q = partition(a, p, r); // 获取分区点
    quickSortInternally(a, p, q-1);
    quickSortInternally(a, q+1, r);
  }
  
  //找出第K大的值
  private static int search(int a[], int i, int j, int k) {
        int m = partition(a, i, j);

        if (k == m - i + 1) {
            return a[m];
        } else if (k < m - i + 1) {//前半段
            return search(a, i, m - 1, k);
        } else {//后半段
            return search(a, m + 1, j, k - (m - i + 1));
        }
    }

  private static int partition(int[] a, int p, int r) {
    int pivot = a[r];
    int i = p;
    for(int j = p; j < r; ++j) {
      if (a[j] < pivot) {
        int tmp = a[i];
        a[i] = a[j];
        a[j] = tmp;
        ++i;
      }
    }
    int tmp = a[i];
    a[i] = a[r];
    a[r] = tmp;

    System.out.println("i=" + i);
    return i;
  }
}
复制代码

堆排序

package sort;
public class HeapSort {
    //创建大顶堆
    void maxHeapify(int array[], int start, int end) {
        //父亲节点
        int parent = start;
        //左孩子节点
        int child = parent * 2 + 1;

        while (child <= end) {//如果子节点下标在可以调整的范围内就一直调整下去
            //如果没有右孩子就不用比,有的话,比较两个儿子,选择最大的出来
            if (child + 1 <= end && array[child] < array[child + 1]) {
                child++;
            }
            if (array[parent] > array[child]) {
                return;
            } else {//父亲比儿子小,就要对整个子树进行调整
                int temp = array[child];
                array[child] = array[parent];
                array[parent] = temp;
                //递归下一层
                parent = child;
                child = child * 2 + 1;
            }
        }
    }


    void heapSort(int[] array, int len) {
        //建堆, len/2-1最后一个非叶子节点
        for (int i = len / 2 - 1; i >= 0; i--) {
            maxHeapify(array, i, len - 1);
        }
        //排序,根节点和最后一个节点交换
        //换完以后,取走根,重新建堆
        //len-1,最后一个节点
        for (int i = len - 1; i > 0; i--) {
            int temp = array[0];
            array[0] = array[i];
            array[i] = temp;
            maxHeapify(array, 0, i - 1);
        }
    }
}
复制代码

计数排序

package sort;

/**
 * 计数排序
 *
 * Author: ZHENG
 */
public class CountingSort {

  // 计数排序,a是数组,n是数组大小。假设数组中存储的都是非负整数。
  public static void countingSort(int[] a, int n) {
    if (n <= 1) return;

    // 查找数组中数据的范围
    int max = a[0];
    for (int i = 1; i < n; ++i) {
      if (max < a[i]) {
        max = a[i];
      }
    }

    // 申请一个计数数组c,下标大小[0,max]
    int[] c = new int[max + 1];
    for (int i = 0; i < max + 1; ++i) {
      c[i] = 0;
    }

    // 计算每个元素的个数,放入c中
    for (int i = 0; i < n; ++i) {
      c[a[i]]++;
    }

    // 依次累加
    for (int i = 1; i < max + 1; ++i) {
      c[i] = c[i-1] + c[i];
    }

    // 临时数组r,存储排序之后的结果
    int[] r = new int[n];
    // 计算排序的关键步骤了,有点难理解
    for (int i = n - 1; i >= 0; --i) {
      int index = c[a[i]]-1;
      r[index] = a[i];
      c[a[i]]--;
    }
    // 将结果拷贝会a数组
    for (int i = 0; i < n; ++i) {
      a[i] = r[i];
    }
  }
}
复制代码

二分查找

public int bsearch(int[] a, int n, int value){
  int low = 0;
  int high = n - 1;
  
  while(low < high){
    int mid = low + (high - low)/2;
    if(a[mid] == value){
      return mid;
    }else if(a[mid] < value){
      low = mid + 1;
    }else{
      high = mid - 1;
    }
  }
  return -1;
}
复制代码

3. 无重复字符的最长子串

public class FindMaxLengthSubString {
    /**
     * 查找最长不重复子序列
     *
     * @param s
     * @return
     */
    public static int lengthOfLongestSubstring(String s) {
        int[] freq = new int[256];
        int l = 0, r = s.length() - 1;//滑动窗口为s[l...r]
        int res = 0;//最大子长度

        while (l < s.length()) {
            if (r + 1 < s.length() && freq[s.indexOf(r + 1)] == 0) {
                r++;
                freq[r]++;
            } else {
                freq[s.indexOf(l)]--;
                l++;
            }
            res = Math.max(res, r - l + 1);
        }
        return res;
    }
}
复制代码

链表

package linklist;

/**
 * 1) 单链表反转
 * 2) 链表中环的检测
 * 3) 两个有序的链表合并
 * 4) 删除链表倒数第n个结点
 * 5) 求链表的中间结点
 *
 * Author: Zheng
 */
public class LinkedListAlgo {

  // 单链表反转
  public static Node reverseList(Node list){
    Node headNode = null;
    Node pCurrentNode = list;
    Node preNode = null;

    while (pCurrentNode != null){
      Node next = pCurrentNode.next;
      if (next == null){
        headNode = pCurrentNode;
      }

      pCurrentNode.next = preNode;
      preNode = pCurrentNode;
      pCurrentNode = next;
    }

    return headNode;

  }

  // 检测环
  public static boolean checkCircle(Node list) {
    if (list == null) return false;

    Node fast = list.next;
    Node slow = list;

    while (fast != null && fast.next != null) {
      fast = fast.next.next;
      slow = slow.next;

      if (slow == fast) return true;
    }

    return false;
  }

  // 有序链表合并
  public static Node mergeSortedLists(Node la, Node lb) {
    if (la == null) return lb;
    if (lb == null) return la;

    Node p = la;
    Node q = lb;
    Node head;
    if (p.data < q.data) {
      head = p;
      p = p.next;
    } else {
      head = q;
      q = q.next;
    }
    Node r = head;

    while (p != null && q != null) {
      if (p.data < q.data) {
        r.next = p;
        p = p.next;
      } else {
        r.next = q;
        q = q.next;
      }
      r = r.next;
    }

    if (p != null) {
      r.next = p;
    } else {
      r.next = q;
    }

    return head;
  }

  // 删除倒数第K个结点
  public static Node deleteLastKth(Node list, int k) {
    Node fast = list;
    int i = 1;
    while (fast != null && i < k) {
      fast = fast.next;
      ++i;
    }

    if (fast == null) return list;

    Node slow = list;
    Node prev = null;
    while (fast.next != null) {
      fast = fast.next;
      prev = slow;
      slow = slow.next;
    }

    if (prev == null) {
      list = list.next;
    } else {
      prev.next = prev.next.next;
    }
    return list;
  }

  // 求中间结点
  public static Node findMiddleNode(Node list) {
    if (list == null) return null;

    Node fast = list;
    Node slow = list;

    while (fast.next != null && fast.next.next != null) {
      fast = fast.next.next;
      slow = slow.next;
    }

    return slow;
  }

  public static void printAll(Node list) {
    Node p = list;
    while (p != null) {
      System.out.print(p.data + " ");
      p = p.next;
    }
    System.out.println();
  }

  public static Node createNode(int value) {
    return new Node(value, null);
  }

  public static class Node {
    private int data;
    private Node next;

    public Node(int data, Node next) {
      this.data = data;
      this.next = next;
    }

    public int getData() {
      return data;
    }
  }

}

复制代码

大整数相加

package interview;

public class BigIntAdd {
    public static void main(String[] args) {
        String n1 = "12345";
        String n2 = "1234567";
        System.out.println("result:" + bigIntAdd(n1, n2));
    }
  
    public static String bigIntAdd(String n1, String n2) {
        StringBuffer result = new StringBuffer();

        int len1 = n1.length();
        int len2 = n2.length();

        boolean overFlow = false;
        int overNum = 0;

        n1 = new StringBuffer(n1).reverse().toString();
        n2 = new StringBuffer(n2).reverse().toString();

        int maxLen = len1 > len2 ? len1 : len2;

        if (len1 < len2) {
            for (int i = len1; i < len2; i++) {
                n1 += "0";
            }
        } else if (len1 > len2) {
            for (int i = len2; i < len1; i++) {
                n2 += "0";
            }
        }
        //
        for (int i = 0; i < maxLen; i++) {
            int sum = Integer.parseInt(n1.charAt(i) + "")
                    + Integer.parseInt(n2.charAt(i) + "") + overNum;
            if (sum >= 10) {
                if (i == maxLen - 1) {
                    overFlow = true;
                }
                overNum = 1;
                result.append(sum - 10);
            } else {
                overNum = 0;
                result.append(sum);
            }
        }
        if (overFlow) {
            result.append(overNum);
        }
        return result.reverse().toString();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值