python实现单链表快速排序升序linkedqueue_排序常⽤算法
时间复杂度
看看有⼏重for循环,只有⼀重则时间复杂度为O(n),⼆重则为O(n^2),依此类推,如果有⼆分则为O(logn),、⼆分查,如果⼀个for 循环套⼀个⼆分,那么时间复杂度则为O(nlogn)。
⼆分查
⼆分查的基本思想是:在有序表中,取中间元素作为⽐较对象,若给定值与中间元素相等,则查成功;若给定值⼩于中间元素,则在中间元素的左半区继续查;若给定值⼤于中间元素,则在中间元素的右半区继续查。不断重复上述过程,直到到为⽌。
从⼆分查的定义我们可以看出,使⽤⼆分查有两个前提条件:
(1)待查的列表必须有序。
(2)必须使⽤线性表的顺序存储结构来存储数据。
int[] arr = new int[]{1, 3, 5, 6, 7, 8, 9};
int target = 8;//⽬标元素
int begin = 0;//开始位置
int end = arr.length - 1;//结束位置
int mid = (begin + end) / 2;//中间位置
int index = -1;//⽬标位置
//循环查
while (true) {
if (arr[mid] == target) {
index = mid;
break;
} else {
//判断中间元素是不是⽐⽬标元素⼤
if (arr[mid] > target) {
end = mid - 1;//把结束为⽌调整到中间的前⼀个位置
} else {
begin = mid + 1;//把开始为⽌调整到中间的位置加1
}
mid = (begin + end) / 2; //取出新的中间位置
}
}
Log.w("TAG", "index---" + index);
冒泡排序
采⽤两两⽐较并交换位置的思路,就仿佛泡泡⼀样,较⼤的元素会慢慢“上浮”1从数列⼀端开始,⽐较相邻两个元素,如果第⼀个元素⽐第⼆个元素⼤,交换两个元素位置然后⽐较第2个数和第3个数,将⼩数放前,⼤数放后,如此继续,2移动⾄下⼀对相邻元素,再次进⾏⽐较和交换,直到数列最后⼀个元素3保证倒数第⼀的元素是数列中最⼤的)4不断重复以上操作。每次重复的时候,需要⽐较的元素个数都减1
//冒泡排序
for (int i = 0; i < arr.length-1; i++) {
for (int j = 0; j < arr.length - i - 1; j++) {
if (arr[j] > arr[j + 1]) {//⼤数在前则交换位置
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
return arr;
}
选择排序
特点:每⼀轮都能选出最⼩的数 最外层开始选择第⼀个数和所有的开始⽐较,原理:每⼀趟从待排序的记录中选出最⼩的元素,顺序放在已排好序的序列最后,直到全部记录排序完毕。
public void choose() {
int[] arr = {5, 2, 8, 4, 9, 1};
//选择排序的优化
for (int i = 0; i < arr.length - 1; i++) {// 做第i趟排序
for (int j = i + 1; j < arr.length; j++) {// 选最⼩的记录
if (arr[i] > arr[j]) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
Log.w("wangwei", "---" + String(arr));
}
快速排序
原理:选择⼀个关键值作为基准值,⼀般选择序列的第⼀个元素。分区,⽐基准值⼩的都在左边序列(⼀般是⽆序的),⽐基准值⼤的都在右边(⼀般是⽆序的再对左右区间重复第⼆步,直到各区间只有⼀个数
挖坑填数
将基准数挖出形成第⼀个坑由后向前出⽐他⼩的数填⼊到第⼀次的坑中,由前向后出⽐基准值打的数放⼊上⼀步拿出去的地⽅-重复执⾏2,3步。
会做n次⼆分 ⼀次为logn n次则就是O(nlogn)
log ⼆分查默认的底数为2
对数 x=log(a)(N) a的x次⽅等于N
//快速排序
public void getKuaiSu() {
int[] a = {5, 3, 9, 1, 6, 7, 2, 4, 0, 8};
quickSort(a, 0, a.length - 1); }
public void quickSort(int[] arr, int start, int end) {
if (start < end) {
int index = getIndex(arr, start, end);//分区索引位
quickSort(arr, 0, index - 1);
quickSort(arr, index + 1, end);
}
}
//分区并返回索引值
private int getIndex(int[] arr, int start, int end) {
//记录需要排序的下标
int i = start;
int j = end;
//第⼀个坑位,基准值,
int x = arr[i];
//循环出⽐基准值⼤的数和⽐基准值⼩的数
while (i < j) {
//先从右向左对⽐出⼩于x的数,arr[j] >= x,不需要移动数据,则继续往前⾛
while (i < j && arr[j] >= x) {
j--;
}
//⽐基准值⼩的时候会跳出上⾯的循环,交换数字
if (i < j) {
//把到的元素放⼊第⼀个坑位
arr[i] = arr[j];
i++;
}
//先从左向右对⽐出⼤于x的数
while (i < j && arr[i] < x) {
i++;
}
if (i < j) {
//把到的元素放⼊第⼀个坑位
arr[j] = arr[i];
j--;
}
}
arr[i] = x;
return i;
}
插⼊排序
假设数列第⼀个元素为已排序数列,剩余数列为未排序将待排序元素挨个插⼊到已排序数列中每次插⼊都必须保证数列是有序的,即通过⽐较和移动有序数列中的元素,将元素插⼊到合适的位置
思路:如同玩扑克牌⼀样,每次摸牌都将它与⼿中的牌⽐较,始终将牌放在⽐它⼤的牌前⾯,⽐它⼩的牌后⾯。这样当牌全部摸到⼿上后,就是⼀个有序的序列。从后往前合适的位置。
//遍历所有的数字,假定第⼀位已经排序,所以从arr[1]开始,
for (int i = 1; i < arr.length; i++) {
//如果当前数字⽐前⼀个⼩
if (arr[i] < arr[i - 1]) {
int temp = arr[i];
int j;
//遍历当前数字,前⾯的数字
for (j = i - 1; j >= 0 && temp < arr[j]; j--) {
//把前⼀个数字给后⾯的
arr[j + 1] = arr[j];
}
arr[j + 1] = temp;
}}
两个有序数组 第k⼩
/**
* 两个有序数组 第k⼩
* ⽅案⼀ 合并遍历
* ⼆:游标计数
* 题⽬只要求第k⼤的数,没必要花⼒⽓将数组全部再排序,
* 可以定义两个游标分别指向两个有序数组,按序移动,并⽤count计数
* ,当count等于k时,返回两个游标指向的数中最⼩的那⼀个
*/
private int arrk() {
int K = 2;
int[] array1 = {3, 6, 7};
int[] array2 = {2, 8, 9};
int i = 0;
int j = 0;
int count = 0;
while (count < K - 1) {
if (array1[i] <= array2[j]) {
i++;
} else {
j++;
}
count++;
}
int ha = array1[i] >= array2[j] ? array2[j] : array1[i];
Log.w("TAG", "---ha-->" + ha);
return ha;
}
快速出⼀个数组中的最⼤数、第⼆⼤数。
思路:如果当前元素⼤于最⼤数 max,则让第⼆⼤数等于原来的最⼤数 max, 再把当前元素的值赋给
* max。如果当前的元素⼤于等于第⼆⼤数secondMax的值 ⽽⼩于最⼤数max的值,则要把当前元素的值赋给 secondMax。*/ int[] arr = { 12, 49, 23, 32, 148, 48, };
int max = arr[0];
for (int i = 0; i < arr.length; i++) {
if (arr[i] > max) {
快速排序python实现max = arr[i];
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论