排序
冒泡排序
遍历n次数组,如果当前数比后一个数大则将当前
数与后一个数交换位置,每遍历一次可排好一个数
的位置,直到n次,时间复杂度为O(N2),排序满足稳定性
public class BubbleSort {
public int[] bubbleSort(int[] ints){
for (int i = 0; i < ints.length; i++) {
for (int j = 1; j < ints.length-i; j++) {
int tmp = ints[j];
if (ints[j]<ints[j-1]){
ints[j] = ints[j-1];
ints[j-1] = tmp;
}
}
}
return ints;
}
public static void main(String[] args) {
int[] ints = {2,5,5};
new BubbleSort().bubbleSort(ints);
for (int i = 0; i < ints.length; i++) {
System.out.println(ints[i]);
}
}
}
选择排序
遍历数组,每一次遍历都会从当前位置之后寻找最小的数,并记录最小数的位置,然后将当前值和最小值交换,完整遍历后可以得到一个顺序列表,时间复杂度为O(N2),排序满足稳定性
public class SelectionSort {
public int[] selectionSort(int[] ints){
for (int i = 0; i < ints.length; i++) {
int first = ints[i];
int tmp = first;
int index = i;
for (int j = i+1; j < ints.length; j++) {
if (ints[j]<tmp){
tmp = ints[j];
index = j;
}
}
ints[i] = ints[index];
ints[index] = first;
}
return ints;
}
public static void main(String[] args) {
int[] ints = {8,6,9,0,8,3,5,7,7};
new SelectionSort().selectionSort(ints);
for (int i = 0; i < ints.length; i++) {
System.out.println(ints[i]);
}
}
}
快速排序
每次排序前先选择一个基准数,然后把比基准数小的放左边,比基准书大的放右边,具体方法是用两个指针,一个从左到右,一个从右到左,左指针找到比基准数大的数时,将左指针的数和右指针的数交换,然后右指针开始向左找比基准书小的数,找到后和左指针的数交换,直到两个指针相遇,此时数组被分成两个区域,再对这两个区域进行快排递归,直到所有数都排好为止
时间复杂度为O(nlogn),在最坏的情况下为O(N2),且不能保证稳定性
public class QuickSort {
public int[] quickSort(int[] ints,int left,int right){
if (left<right){
int baseNum = ints[left];
int l = left;
int r = right;
while (l<r){
while (ints[r]>=baseNum&&l<r){
r--;
}
if (l<r){
ints[l] = ints[r];
}
while (ints[l]<=baseNum&&l<r){
l++;
}
if (l<r){
ints[r] = ints[l];
}
}
ints[l] = baseNum;
quickSort(ints,left, r-1);
quickSort(ints,l+1,right);
}
return ints;
}
public static void main(String[] args) {
int[] ints = {2,5,5};
new QuickSort().quickSort(ints,0,ints.length-1);
for (int i = 0; i < ints.length; i++) {
System.out.println(ints[i]);
}
}
}
归并排序
分治的思想,先将整个数组一分为二,再二分为四…直到分成一个部分只有一个元素为止,这是分的思想。将分出来的部分合并为一个有序的部分,两个已经排好序的部分合并就比较容易了,每一次只需要比较头元素的大小,然后选择小的那个加入到中间数组里即可,用递归的方法可以很好的实现这个思想
时间复杂度稳定为O(nlogn),并且能保证稳定性
public class MergeSort {
public void sort(int[] ints,int left, int right){
int[] tmp = new int[ints.length];
if (left<right){
int mid = (left+right)/2;
sort(ints,left,mid);
sort(ints,mid+1,right);
merge(ints,left,mid,right,tmp);
}
}
private void merge(int[] ints,int left,int mid,int right,int[] tmp){
int l = left;
int r = mid+1;
int index = 0;
while (l<=mid||r<=right){
if (l>mid){
tmp[index++] = ints[r++];
continue;
}
if (r>right){
tmp[index++] = ints[l++];
continue;
}
if (ints[l]<ints[r]){
tmp[index++] = ints[l++];
}
else {
tmp[index++] = ints[r++];
}
}
index = 0;
for (int i = left; i <= right; i++) {
ints[i] = tmp[index++];
}
}
public static void main(String[] args) {
int[] ints = {8,6,9,0,8,3,5,7,7};
new MergeSort().sort(ints,0,ints.length-1);
for (int i = 0; i < ints.length; i++) {
System.out.println(ints[i]);
}
}
}
堆排序
将数据重新排列成一个最小堆,即每个结点的父节点都小于其子结点,这样顶部的元素一定是当前堆的最小值,将顶部元素取出并将叶子结点放置到顶部元素,这样操作后可能会破坏最小堆的结构,所以此时需要重新生成最小堆,这样又可以得出这个堆的最小值,这样重复操作,直到所有数都被取出
时间复杂度稳定为O(nlogn),并且保证稳定性
public class HeapSort {
public void heapSort(int[] ints){
//形成最小堆
for (int i = ints.length-1; i > 0;) {
//只有一个子结点且为左子结点
if (i%2!=0){
int father = i/2;
if (ints[father]>ints[i]){
int tmp = ints[father];
ints[father] = ints[i];
ints[i] = tmp;
}
i--;
}
else {
int father = (i-1)/2;
int small = ints[i]<ints[i-1]?ints[i]:ints[i-1];
int smallIndex = ints[i]<ints[i-1]?i:i-1;
if (small<ints[father]){
int tmp = ints[father];
ints[father] = ints[smallIndex];
ints[smallIndex] = tmp;
arrange(ints,smallIndex, ints.length);
}
i-=2;
}
}
int lastIndex = ints.length-1;
for (int i = 0; i < ints.length; i++) {
int tmp = ints[lastIndex];
ints[lastIndex--] = ints[0];
ints[0] = tmp;
arrange(ints,0,lastIndex+1);
}
}
private void arrange(int[] ints,int index,int intsLength){
int leftChildIndex;
int rightChildIndex;
//判断有无左子节点
if (index*2+1<intsLength){
leftChildIndex = index*2+1;
//有两个结点的情况
if ((index+1)*2<intsLength){
rightChildIndex = (index+1)*2;
int small = ints[leftChildIndex]<ints[rightChildIndex]?ints[leftChildIndex]:ints[rightChildIndex];
int smallIndex = ints[leftChildIndex]<ints[rightChildIndex]?leftChildIndex:rightChildIndex;
if (small<ints[index]){
int tmp = ints[index];
ints[index] = ints[smallIndex];
ints[smallIndex] = tmp;
}
arrange(ints,smallIndex,intsLength);
}
//只有一个子节点的情况
else {
if (ints[leftChildIndex]<ints[index]){
int tmp = ints[index];
ints[index] = ints[leftChildIndex];
ints[leftChildIndex] = tmp;
}
}
}
}
public static void main(String[] args) {
int[] ints = {1,2,3,4,5,6,7,8,9,10,11};
new HeapSort().heapSort(ints);
for (int i = 0; i < ints.length; i++) {
System.out.println(ints[i]);
}
}
}
更多内容
更多内容请看我的个人网站,新建网站,目前内容较少,敬请期待