常用算法java汇总

最近在面试的时候,面试官都会问到一些算法题,这里我把一些课本上有的(算法导论)算法的java实现版本整理一下,方便自己查阅,如果里面存在错误的话,请及时指正,谢谢。

1:快排

快排的思想是分支,具体介绍请查看别的博客,这里我主要说明两点内容:

1)为什么最后需要把你选择的某个anchor点交换,比如说,我在程序里面使用的输入数组的第一个元素,为什么需要把第一个元素和end指针(end指针用于从后往前找到小于anchor的点)进行交换?因为如果你不进行交换的话,对于一些偏序的情况,如倒序的情况,是不可行的。而且,每次交换元素之后保证了我们每次至少有一个元素是已经排好序的。

2)对于选择第一个元素作为anchor点时,必须首先从后开始往前找小于anchor的点,因为这样保证的end指针找的节点是小于anchor的,可以用于交换。如果反过来,首先从前找到大于anchor的点,那么end指向的点可能大于anchor,就不能用于交换(end到达start处停止循环)

package Algorithm;

public class QuickSort {

	public static void main(String[] args) {
		int arr[] = {10, 7, 8, 9, 1, 5}; 
		//int arr[] = {10, 10, 10, 10, 10}; 
        int n = arr.length; 
  
        QuickSort ob = new QuickSort(); 
        ob.sort(arr, 0, n-1); 
  
        System.out.println("sorted array"); 
        printArray(arr); 

	}
	int partition(int arr[], int low, int high) 
    { 
        int pivot = arr[high];  
        int i = (low-1); // index of smaller element 
        for (int j=low; j<high; j++) 
        { 
            if (arr[j] <= pivot) 
            { 
                i++; 
                int temp = arr[i]; 
                arr[i] = arr[j]; 
                arr[j] = temp; 
            } 
        } 
  
        // swap arr[i+1] and arr[high] (or pivot) 
        // 为什么要进行交换,因为保证第i+1位一定是已经排好序的,然后只需对前面和后面排序即可,不用对该位再进行排序
        int temp = arr[i+1]; 
        arr[i+1] = arr[high]; 
        arr[high] = temp; 
  
        return i+1; 
    } 

	public static int partion(int[] data, int startIndex, int endIndex) {
		int start = startIndex;
		int end = endIndex;
		int pivot  = data[startIndex];
		while(start<end) {
			//不能够从左先找,因为从左先找的话,找到的一定是一个大于pivot的数,因此无法和pivot互换
			while(data[end]>pivot && start<end) {
				end--;
			}
			while(data[start]<=pivot && start<end) {
				start++;
			}
			int temp = data[start];
			data[start] = data[end];
			data[end] = temp;
		}
		int temp = data[end];
		data[end] = data[startIndex];
		data[startIndex] = temp;
		return end;
	}

  void sort(int arr[], int low, int high) 
  { 
      if (low < high) 
      { 	
          int pi = partion(arr, low, high); 
          // or int pi = partition(arr, low, high);	
          printArray(arr);
          sort(arr, low, pi-1); 
          sort(arr, pi+1, high); 
      } 
  } 

  static void printArray(int arr[]) 
  { 
      int n = arr.length; 
      for (int i=0; i<n; ++i) 
          System.out.print(arr[i]+" "); 
      System.out.println(); 
  } 
}

参考:

https://www.geeksforgeeks.org/quick-sort/

2:堆排序

堆排序的详细细节请查看别的博客,这里我主要说一点,就是建堆的时间复杂度是O(n),虽然建堆过程需要对非叶子节点进行堆维护过程,看起来像是O(NlogN),但是,因为不是所有节点都需要维护堆,而且需要维护的节点树高比较低,因此实际的时间复杂度上界是O(n),证明如下(拍自算法导论):

常用算法java汇总

package Algorithm;

public class HeapSort {

	public static void main(String[] args) {
 
	        int arr[] = {12, 11, 13, 5, 6, 7}; 
	  
	        HeapSort ob = new HeapSort(); 
	        ob.sort(arr); 
	  
	        System.out.println("Sorted array is"); 
	        printArray(arr); 

	}
	public void sort(int[] arr) {
		int length = arr.length;
		for(int i=length/2-1;i>=0;i--) {
			heapify(arr, length, i); 
		}
		 for (int i=length-1; i>=0; i--) 
	        { 
	            // Move current root to end 
	            int temp = arr[0]; 
	            arr[0] = arr[i]; 
	            arr[i] = temp; 
	  
	            // call max heapify on the reduced heap 
	            heapify(arr, i, 0); 
	        } 
	}
	void heapify(int arr[], int n, int i) {
		int largest = i; // Initialize largest as root 
        int l = 2*i + 1; // left = 2*i + 1 
        int r = 2*i + 2; // right = 2*i + 2 
  
        // If left child is larger than root 
        if (l < n && arr[l] > arr[largest]) 
            largest = l; 
  
        // If right child is larger than largest so far 
        if (r < n && arr[r] > arr[largest]) 
            largest = r; 
  
        // If largest is not root 
        if (largest != i) 
        { 
            int swap = arr[i]; 
            arr[i] = arr[largest]; 
            arr[largest] = swap; 
  
            // Recursively heapify the affected sub-tree 
            heapify(arr, n, largest); 
        } 
	}
	 static void printArray(int arr[]) 
	    { 
	        int n = arr.length; 
	        for (int i=0; i<n; ++i) 
	            System.out.print(arr[i]+" "); 
	        System.out.println(); 
	    } 
}

参考:

https://www.geeksforgeeks.org/heap-sort/

相关文章: