通过构建有序序列,对于末排数据,在已排序序列中从后向前扫描,找到相应的位置并插入
特点:效率低,容易实现
思路:将数组分为两部分,将后部分元素逐一与前部分元素比较,
如果前部分元素比array[i]小,就将前部分元素往后移,
当没有比array[i]小的元素,即是合理位置,在此位置插入array[i]
例:非常类似于整理扑克牌:从开始摸牌时,左手是空的,牌面朝下放在桌上。
接着,一次从桌上摸起一张牌,并将它插入到左手一把牌中的正确位置上。
为了找到这张正确位置,要将它与手中已有的牌从右到左的进行比较,无论什么时候,左手的牌都是排好序的
代码实现:
public void insertionSort(int array[]) {
int i, j, t = 0;
for (i = 1; i < array.length; i++) {
if(a[i]<a[i-1]){
t = array[i];
for (j = i - 1; j >= 0 && t < array[j]; j--)
array[j + 1] = array[j];
//插入array[i]
array[j + 1] = t;
}
}
}
冒泡排序
特点:效率低,实现简单
思路:每一趟将待排序序列中最大元素移到最后,剩下的为新的待排序序列,重复上述步骤直到排完所有元素,这只是冒泡排序的一种,当然也可以从后往前排
代码实现:
public void bubbleSort(int array[]) {
int t = 0;
for (int i = 0; i < array.length - 1; i++)
for (int j = 0; j < array.length - 1 - i; j++)
if (array[j] > array[j + 1]) {
t = array[j];
array[j] = array[j + 1];
array[j + 1] = t;
}
}
选择排序
特点:效率低,容易实现
思路:每一趟从待排序序列选择一个最小的元素放到已排好序序列的末尾,剩下的为待排序序列,重复上述步骤直到完成排序
代码实现:
public void selectSort(int array[]) {
int t = 0;
for (int i = 0; i < array.length - 1; i++){
int index=i;
for (int j = i + 1; j < array.length; j++)
if (array[index] > array[j])
index=j;
if(index!=i){ //找到了比array[i]小的则与array[i]交换位置
t = array[i];
array[i] = array[index];
array[index] = t;
}
}
}
二分查找
特点:称为折半查找,属于有序查找算法,元素必须是有序的,如果是无序的则要先进行排序操作
思路:用给定值先与中间结点的关键字比较,中间结点把线形表分为两个子表,若相等则成功,若不相等,在根据值与该中间结点关键字的比较,结果确定下一步查找哪个子表,进行递归直到查找结束
代码实现:
public class BinarySearch {
/**
* 二分查找算法
*
* @param srcArray 有序数组
* @param key 查找元素
* @return key的数组下标,没找到返回-1
*/
public static void main(String[] args) {
int srcArray[] = {3,5,11,17,21,23,28,30,32,50,64,78,81,95,101};
System.out.println(binSearch(srcArray, 0, srcArray.length - 1, 81));
}
// 二分查找递归实现
public static int binSearch(int srcArray[], int start, int end, int key) {
int mid = (end - start) / 2 + start;
if (srcArray[mid] == key) {
return mid;
}
if (start >= end) {
return -1;
} else if (key > srcArray[mid]) {
return binSearch(srcArray, mid + 1, end, key);
} else if (key < srcArray[mid]) {
return binSearch(srcArray, start, mid - 1, key);
}
return -1;
}
// 二分查找普通循环实现
public static int binSearch(int srcArray[], int key) {
int mid = srcArray.length / 2;
if (key == srcArray[mid]) {
return mid;
}
int start = 0;
int end = srcArray.length - 1;
while (start <= end) {
mid = (end - start) / 2 + start;
if (key < srcArray[mid]) {
end = mid - 1;
} else if (key > srcArray[mid]) {
start = mid + 1;
} else {
return mid;
}
}
return -1;
}
}
顺序查找
称为线性查找,属于无序查找算法,适合于存储结构为顺序存储,或链接存储的线性表
思路:从数据结构线性表的一端开始,依次将扫描到的结点关键字与给定值相比较,若相等则成功,若不相等,则查找失败
代码实现:
package search;
import java.util.Scanner;
/*通常把查找过程中对关键字的平均比较次数,也叫平均查找长度(ASL)作为衡量一个查找算法效率优劣的标准:
* ASL=求和(p[i]*c[i]),(i=1~n)。P[i]找到第i个记录的概率,c[i]找到第i个记录进行比较的次数*/
/*顺序查找的思想:从表的一端开始,顺序扫描线性表,依次将扫描到的关键字和给定值k比较,若当前扫描的关键字与k相等,则查找成功,
* 若扫描结束后,任未发现关键字等于k的记录,则查找失败。
* ASL1查找成功(求和)i/n,i=1~n.
* ASL2查找失败n*/
//第一行输入要查找的序列,第二行输入关键字
public class shunxusearch {
public static void main(String[] args){
Scanner cin = new Scanner(System.in);
String[] s= new String[2];
for(int i =0;i<2;i++){
s[i] = cin.nextLine();
}
String[] st = s[0].split(" ");
int[] c = new int[st.length];
for(int j=0;j<st.length;j++){
c[j]=Integer.parseInt(st[j]);
}
int key = Integer.parseInt(s[1]);
int result = search(c,key);
System.out.println(result);
cin.close();
}
public static int search(int[] R,int k){
int i,n=R.length;
for(i=0;i<n;i++){
if(R[i]==k){
return i;
}
}
return -1;
}
}