在軟件開發中,有兩個常見的任務,一個是某一組中查找某個特定的元素,另一個是將某一組元素按照特定的順序排序。我們可以使用多種算法來完成這些任務,而這些算法的差異也是值得我們去仔細研究的,接下來我們探究一下這些算法。
一、查找
1.1、線性查找法 線性查找就是通過索引對數組data的每個元素進行遍歷,如果發現要找的目標元素和數組data中的某個元素相同時,就返回已經查找到,當然,我們也是可以改進一下,就是直接把找到的元素返回即可。
public static <T extends Comparable<? super T>>
boolean linearSearch(T[] data, int min , it max, T target)
{int index = min;boolean found = false;while(!found && index <= max){//判斷界限if(data[index].compareTo(target) == 0){found = true;}index++;}return found;
}
1.2、二分查找法 二分查找法的效率比線性搜索法高,因為不用全部遍歷一遍,節省了很多的時間,這里我們采用的方法是遞歸調用來進行查找的,如果發現中點位置的元素大小小于目標元素,就將中點位置的索引+1,進行遞歸調用,如果大于目標元素,就將中點位置索引-1,進行遞歸調用,而遞歸的出口就是,當中點位置的值和目標元素的值相等時,則返回結果。
public static <T extends Comparable<? super T>>
boolean binarySearch(T[] data, int min , it max, T target)
{boolean found = false;int midpoint = (min+max)/2;//選擇中點位置if(data[midpoint].compareTo(target) == 0){found = true;} else if(data[midpoint].compareTo(target) > 0){if(min <= midpoint - 1){found = binarySearch(data, min, midpoint - 1, target);}} else if(data[midpoint].compareTo(target) > 0){if(max >= midpoint + 1){found = binarySearch(data, min, midpoint + 1, target);}
}
二、排序
排序分為 順序排序:選擇,插入,冒泡排序; 對數排序:快速,歸并排序;
2.1、選擇排序 通過掃描整個列表找出最小值,將這個值與該列表的第一個位置的值交換。掃描剩余(除了第一個值)部分列表并找出最小值,然后將它和該列表的第二個位置處的值交換。以此類推下去。
public static <T extends Comparable<? super T>>
void selectionSort(T[] data){int min ;//定義存儲掃描的最小值T temp;for(itn index = 0; index < data.length - 1; index++){min = index;//初始化為最小值為第一個for(int scan = index + 1; scan < data.length - 1; scan++){if(data[scan].compareTo(data[min]) < 0){//如果小于最小值,就將找到的最小值賦值給當前的最小值min = scan;}}//將找到的最小值和當前的第一個位置交換temp = data[min];data[min] = data[index];data[index] = temp;}
}
外層循環控制下一個最小值將保存在數組中的哪個位置,內層循環通過掃描所有大于或者等于外層循環制定索引的位置來查找剩余部分的列表的最小值。
這里提取一個互換的函數 :
//兩個元素交換位置
private static <T extends Comparable<T>> void swap
(T[] data, int index1, int index2){T temp = data[index];data[index1] = data[index2];data[index2] = temp;
}
2.2、插入排序 插入排序算法通過反復的將某個特定的值插入到該列表某個已排序的子集中來完成對列表值得排序。 策略:將列表中的頭兩個值依據其相對大小對其進行排序,將列表的第三個值插入到頭兩個已排序的值中的恰當位置,然后將第四個值插入到前三個已排序的恰當位置。
public static <T extends Comparable<? super T>>
void selectionSort(T[] data){for(int index = 1; index < data.length; index++){T key = data[index];//將這個元素暫時保存int position = index;//外層循環保存索引//查找更大的元素到對的位置while(position > 0 && data[position - 1].compareTo(key) > 0){data[position] = data[position - 1];position --;}data[position] = key;}
}
2.3、冒泡排序 重復的比較列表中的相鄰的元素,如果發現某個相鄰的元素的位置不對的時候,就將這兩個元素的位置交換。
public static <T extends Comparable<? super T>>
void selectionSort(T[] data){int position ,scan;T temp;for(position = data.length - 1; position >=0; position --){for(scan = 0; scan <= position - 1; scan++){if(data[scan].compareTo(data[scan+1]) > 0){swap(data,scan, scan + 1);}}}
}
2.4、快速排序 通過任意選定的分區元素將該列表分區,然后對分區元素的任一邊的子列表進行遞歸排序。
public static <T extends Comparable<T>> void quickSort(T[] data){quickSort(data, 0, data.length-1);
}public static <T extends Comparable<T>> void quickSort(T[] data, min , max){if(min < max){//創建分區索引int indexOfPartition = partition(data, min, max);//對左分區進行遞歸排序quickSort(data, min, indexOfPartition -1);//對右分區進行遞歸排序quickSort(data, indexOfPartition + 1, max);}
}public static <T extends Comparable<T>> void partition(T[] data, int min , int max){T partitionelement;int left, right;int middle = (min+max)/2;//使用中間數據值作為分區元素partitionelement = data[middle];//將第一個元素和分區元素交換位置swap(data,middle,min);left = min;right = max;while(left < right){//如果左邊的元素比分區元素小就索引右移查找下一個while(left< right && data[left].compareTo(partitionelement) <= 0){left ++;}//如果右邊元素比分區元素大就索引左移查找下一個元素while(data[right].compareTo(partitionelement) > 0){right ++;}if(left < right){swap(data,left,right);}}//將分區元素放回到原來的位置swap(data, min, right);return right;
}
2.5、歸并排序
將列表分成大約相等的兩個部分,然后對每一部分列表遞歸調用其本身,繼續該列表的遞歸分解,直至達到該遞歸的基本情形,這是列表被分割成長度為1的列表,根據定義,此時已排序好。
private static <T extends Comparable<T>> void mergeSort(T[] data, int min , int max){if(min < max){int mid = (min+max)/2;mergeSort(data,min,mid);mergeSort(data,mid+1,max);merge(data,min,mid,max);}
}private static <T extends Comparable<T>> void merge(T[] data, int first , int mid, int last){T[] temp = (T[])(new Comparable[data.length]);int first1 = first, last1 = mid;int first2 = mid+1, last2 = last;int index = first1;//復制每一個子序列中的更小的元素到temp數組中,直到已排序好while(first1 <= last1 && first2 <= last2){if(data[first1].compareTo(data[first2]) < 0){temp[index] = data[first1];first1++;} else {temp[index] = data[first2];first2++;}index++;}//從第一個子序列中復制剩余的元素到temp數組中while(first1 <= last1){temp[index] = data[first1];first1++;index++;}//從第二個子序列中復制剩余的元素到temp數組中while(first2 <= last2){temp[index] = data[first2];first2++;index++;}//復制歸并數據temp到原始的序列中for(index = first; index <= last; index++){data[index] = temp[index];}
}
總結
以上是生活随笔 為你收集整理的数据结构与算法-排序与查找(java描述) 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。