您的位置:首页 > 理论基础 > 数据结构算法

Java数据结构--排序

2016-04-27 15:37 375 查看
最近实验室的技术沙龙开展起来了,我想着讲点基础的,讲讲最基本的排序算法吧。相比于画图讲思想,我更喜欢实现了的代码,所以我就根据代码写一下。(代码默认升序排列)

插入排序:

//插入排序
public static void InsertSort(int[] num){
if (num.length<=0) {   //判断数组是否为空
return;
}
//插入排序的思想是:将选取的元素插入到有序序列,依次插入,直到所有元素有序
for (int i = 1; i < num.length; i++) {
int tmp = num[i];
int j=i-1;
while(num[j]>tmp){
num[j+1]=num[j];  //如果比tmp大,则后移
j--;
if (j<0) {
break;
}
}

num[j+1]=tmp;       //直到找到一个比tmp小或者到了起始点,将其插入
}
}


冒泡排序:

//冒泡排序
public static void BubbleSort(int[] num) {
if(num.length<=0) return;
//冒泡排序的思想在于取其中一个元素与相邻元素比较,较大者上浮,直到最大的浮到底部
boolean change = true; //此变量为优化算法的比较次数,当有一趟所有元素都未发生交换说明已有序
for (int i = 0; i < num.length&&change; i++) {
change = false;
for (int j = 0; j < num.length-i-1; j++) {
if(num[j]>num[j+1]){
int tmp = num[j];
num[j] = num[j+1];
num[j+1] = tmp;
change = true;
}
}
}
}


快速排序:(由于比较重要,解释的清楚些)

快速排序是找出一个元素(理论上可以随便找一个)作为基准(pivot),然后对数组进行分区操作,使基准左边元素的值都不大于基准值,基准右边的元素值 都不小于基准值,如此作为基准的元素调整到排序后的正确位置。递归快速排序,将其他n-1个元素也调整到排序后的正确位置。最后每个元素都是在排序后的正 确位置,排序完成。所以快速排序算法的核心算法是分区操作,即如何调整基准的位置以及调整返回基准的最终位置以便分治递归。

举例说明一下吧,这个可能不是太好理解。假设要排序的序列为

2 2 4 9 3 6 7 1 5 首先用2当作基准,使用i j两个指针分别从两边进行扫描,把比2小的元素和比2大的元素分开。首先比较2和5,5比2大,j左移

2 2 4 9 3 6 7 1 5 比较2和1,1小于2,所以把1放在2的位置

2 1 4 9 3 6 7 1 5 比较2和4,4大于2,因此将4移动到后面

2 1 4 9 3 6 7 4 5 比较2和7,2和6,2和3,2和9,全部大于2,满足条件,因此不变

经过第一轮的快速排序,元素变为下面的样子

[1] 2 [4 9 3 6 7 5]

之后,在把2左边的元素进行快排,由于只有一个元素,因此快排结束。右边进行快排,递归进行,最终生成最后的结果。

//快速排序
public static void QuickSort(int[] num,int left,int right) {
if(num.length<=0) return;
//快拍是一种分治思想的排序,每次选取一个元素p,把序列分为两个部分,比p小的和比p大的,然后迭代
//直到有序为止
if(left<right) {
int p = num[left];
int low,high;
low = left;
high = right;
while (low<high) {
while (low<high&&num[high]>p) {
high--;
}
num[low] = num[high];
while (low<high&&num[low]<p) {
low++;
}
num[high] = num[low];
}
num[low] = p;
QuickSort(num, left, low-1);
QuickSort(num, low+1, right);
}
}


选择排序:

//选择排序
public static void SelectSort(int[] num) {
if(num.length<=0) return;
//选择排序是选取一个临时变量来记录每一躺的最大值,然后放在序列的尾端
for(int i =0;i<num.length;i++){
int x=num[i];
int y=i;
int j;
for (j = i; j < num.length; j++) {
if(num[j]<x){
x=num[j];
y=j;
}
}
num[y]=num[i];
num[i]=x;

}
}


归并排序:

//归并排序
public static void MergeArray(int[] num,int left,int mid,int right) {
int i=left,j=mid+1,k=0;
int[] tmp = new int[right-left+1];
while (i<=mid&&j<=right) {
if (num[i]>num[j]) {
tmp[k++] = num[j++];
}
else {
tmp[k++] = num[i++];
}
}
while (i<=mid) {
tmp[k++] = num[i++];
}
while (j<=right) {
tmp[k++] = num[j++];
}
int m=0;
for (int l = left; l < right+1; l++) {
num[l] = tmp[m++];
}
}
public static void MergeSort(int[] num,int left,int right) {
//归并排序的思想是将序列划分成两段,然后用递归,直到序列只有两个元素,然后将有序的序列进行合并
if(left<right){
int mid = (left+right)/2;
MergeSort(num, left, mid);
MergeSort(num, mid+1, right);
MergeArray(num, left, mid, right);
}
}


下面是每种算法的时间复杂度和空间复杂度:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: