冒泡排序
基本概念
冒泡排序(Bubble Sort,台湾译为:泡沫排序或气泡排序)是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。
主要思路就是 每一次遍历都两两比较,大的或者小的放在后面或者前面;
代码
public class BubbleSort {
public static void main(String[] args) {
int[] nums = new int[] {12,6,21,54,4,5,21,1};
bubbleSort(nums);
for (int i : nums) {
System.out.println(i);
}
}
public static void bubbleSort(int nums[]) {
int len = nums.length;
int t; //交换中间数
for(int i = 0;i<len -1;i++) {
for(int j = 0;j<(len -1 -i);j++) {
if(nums[j] > nums[j+1]) {
t = nums[j+1];
nums[j+1] = nums[j];
nums[j] = t;
}
}
}
}
}
选择排序
基本概念
首先在未排序的数列中找到最小(or最大)元素,然后将其存放到数列的起始位置;接着,再从剩余未排序的元素中继续寻找最小(or最大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕
代码
public static void selectionSort(int[] arr){
int len = arr.length;
int minIndex;
int tmp;
for(int i = 0;i < len - 1;i++){
minIndex = i;
for(int j = i + 1;j < len;j++){
if(arr[j] < arr[minIndex]){
minIndex = j;
}
}
if(i != minIndex){
tmp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = tmp;
}
}
}
快速排序
基本概念:
通过一趟排序将记录分割成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序的目的
代码:
/****
* 快速排序
* @throws Exception
*/
@Test
public void testQuickSort() throws Exception{
int[] arr = {3, 44, 38, 5, 47, 15,12,23,45,2,6,4};
//这里有用来spring的东西,可以去掉
ObjectMapper om = new ObjectMapper();
quickSort(arr,0,arr.length-1);
System.out.println(om.writeValueAsString(arr));
}
/***
* 快速排序的实现
* @param arr
* @param left
* @param right
*/
public void quickSort(int[] arr , int left , int right){
if(left >= right ) return; //结束条件
int start = left; //记录起始位置的值
int end = right; //记录结束位置的值
int number = arr[start]; //基数
while(left < right){
//寻找右边比基数小的值
while(left < right && arr[right] >= number){
right -- ;
}
//寻找左边比基数小的值
while(left < right && arr[left] <= number){
left++;
}
//当找到值后,并且两者不是同一个数则进行交换
if(left < right){
swap(arr, left, right);
}
}
//当循环结束后;将基数放到合适的位置
swap(arr, start, left); //此时left和right相等
quickSort(arr,start,left-1);
quickSort(arr,right+1,end);
}
//交换
public void swap(int[] arr,int i,int j){
if(i == j) return;
int tem = arr[i];
arr[i] = arr[j];
arr[j] = tem;
}
归并排序
基本概念
使用分治法,先将一个序列两两划分,分成一个个子序列,使子序列有序,最后合并有序子序列;
在划分过程中最后生成的子序列都是含有一个元素的,因此可以看成是有序,在第一次合并之后,一般情况下是每个序列都有两个元素(由于第一次的合并是按照有序合并,因此合并之后的子序列都是有序的),然后不断的合并。
代码
链表
public static void UseMergeSort(int[] arr){
mergeSort(arr,0,arr.length - 1,new int[arr.length]);
}
public static void mergeSort(int[] arr,int left,int right,int[] tmp){
if(left < right){
int mid = (right - left) / 2 + left;
mergeSort(arr,left,mid,tmp);
mergeSort(arr, mid+1, right,tmp);
for( int i = left;i <= right;i++){
tmp[i] = arr[i];
}
int r = mid+1;
int l = left;
int index = left;
//两个有序子序列的处理
while(l <= mid && r <= right){
arr[index++] = tmp[l] < tmp[r] ? tmp[l++]:tmp[r++];
}
while(l <= mid){
arr[index++] = tmp[l++];
}
while(r <= right){
arr[index++] = tmp[r++];
}
}
链表
class MergeSortLinkNode{
int val;
MergeSortLinkNode next;
MergeSortLinkNode(int val){
this.val = val;
next = null;
}
@Override
public String toString() {
return "MergeSortLinkNode [val=" + val + ", next=" + next + "]";
}
}
public class TestMergeSortLink {
//初始化链表
private static MergeSortLinkNode initLink(int[] array) {
MergeSortLinkNode head = new MergeSortLinkNode(0);
MergeSortLinkNode curr = head;
for (int i : array) {
curr.next = new MergeSortLinkNode(i);
curr = curr.next;
}
return head.next;
}
//测试
public static void main(String[] args) {
MergeSortLinkNode head = initLink(new int[]{1,6,3,8,6,4,3,0,9,8,5,2,11,24,66,7});
head = merge(head);
System.out.println(head);
}
//合并
private static MergeSortLinkNode merge(MergeSortLinkNode head) {
if(head == null || head.next == null) {
return head;
}
MergeSortLinkNode left = head;
MergeSortLinkNode right = head.next;
while(right != null && right.next != null) {
left = left.next;
right = right.next.next;
}
right = left.next;
left.next = null;
left = head;
left = merge(left);
right = merge(right);
return sort(left,right);
}
//排序
private static MergeSortLinkNode sort(MergeSortLinkNode left,MergeSortLinkNode right) {
MergeSortLinkNode head = new MergeSortLinkNode(0);
MergeSortLinkNode curr = head;
while(left != null && right != null) {
if(left.val > right.val) {
curr.next = right;
right = right.next;
}else {
curr.next = left;
left = left.next;
}
curr = curr.next;
}
if(left != null) {
curr.next = left;
}
if(right != null) {
curr.next = right;
}
return head.next;
}
}