当前位置: 首页 > news >正文

网页设计与网站建设课程网络培训中心

网页设计与网站建设课程,网络培训中心,做瞹瞹嗳视频网站,网站验证码系统作者:✿✿ xxxflower. ✿✿ 博客主页:xxxflower的博客 专栏:【数据结构】篇 语录:⭐每一个不曾起舞的日子,都是对生命的辜负。⭐ 文章目录1.排序1.1排序的概念1.2常见的排序算法2.常见排序算法2.1插入排序2.1.1直接插入…

作者:✿✿ xxxflower. ✿✿
博客主页:xxxflower的博客
专栏:【数据结构】篇
语录:⭐每一个不曾起舞的日子,都是对生命的辜负。⭐

文章目录

  • 1.排序
    • 1.1排序的概念
    • 1.2常见的排序算法
  • 2.常见排序算法
    • 2.1插入排序
      • 2.1.1直接插入排序
      • 2.1.2希尔排序(缩小增量排序)
    • 2.2选择排序
      • 2.2.1基本思想
      • 2.2.3 堆排序
    • 2.3交换排序
      • 2.3.1冒泡排序
      • 2.3.2快速排序
      • 2.3.2快速排序的优化
      • 2.3.3快速排序
      • 2.3.5非递归实现快速排序
    • 2.4 归并排序
      • 2.4.1递归实现归并排序
      • 2.4.2非递归的归并排序
  • 3.排序的总结
      • 计数排序

1.排序

1.1排序的概念

排序:所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。
稳定性:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i]=r[j],且r[i]在r[j]之前,而在排序后的序列中,r[i]仍在r[j]之前,则称这种排序算法是稳定的;否则称为不稳定的。
在这里插入图片描述
内部排序:数据元素全部放在内存中的排序。
外部排序:数据元素太多不能同时放在内存中,根据排序的要求不能在内外存之间移动数据的排序。

1.2常见的排序算法

在这里插入图片描述

2.常见排序算法

2.1插入排序

插入排序的基本思想是:把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列 。实际中我们玩扑克牌时,就用了插入排序的思想。

2.1.1直接插入排序

请添加图片描述

public static void insertSort(int[] array){for (int i = 1; i < array.length; i++) {int tmp = array[i];int j = i-1;for (;j >= 0;j--) {if(array[j] > tmp){array[j+1] = array[j];}else{break;}}array[j+1] = tmp;}}

我们来分析一下插入排序时间复杂度:
最好情况下:顺序。O(N)
最坏情况下:逆序。O(N^2)
在这里插入图片描述
因此我们可以得出一个结论:当数据量不多,且基本上趋于有序的时候,直接插入排序是非常快的。
空间复杂度:O(1)
稳定性:稳定

2.1.2希尔排序(缩小增量排序)

希尔排序法又称缩小增量法。希尔排序法的基本思想是:先选定一个整数,把待排序文件中所有记录分成个组,所有距离为的记录分在同一组内,并对每一组内的记录进行排序。然后,取,重复上述分组和排序的工作。当到达=1时,所有记录在统一组内排好序。
在这里插入图片描述

//希尔排序private static void shell(int[] array,int gap){for(int i = gap;i < array.length;i++){int tmp = array[i];int j = i - gap;for(;j >= 0;j -= gap){if(tmp > array[j]){array[j+gap] = array[j];}else{break;}}array[i+gap] = tmp;}}public static void shellSort(int[] array){int gap = array.length;while(gap > 1){gap /= 2;shell(array,gap);}}

希尔排序的时间复杂度是数学上未解决的题,它会随着组别的变化而变化。但是大量的实验的得出局部的结论:O(N^1.3)
稳定性:不稳定。
空间复杂度:O(1)。
希尔排序实际上是对直接插入排序的优化。它使得数字趋于有序化,最后在进行直接插入排序。

2.2选择排序

2.2.1基本思想

每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完 。
在这里插入图片描述
方法一:

//选择排序public static  void selectSort(int[] array){for(int i = 0;i < array.length;i++){int minIndex = i;for(int j = i+1;j < array.length;j++){if(array[j] < array[minIndex]) {minIndex = j;}}//处理两个下标一样的情况,比如第一个数就是最大值,后面找不到比它小的值if(i != minIndex){swap(array,minIndex,i);}}}public static void swap(int[] array,int i,int j){int tmp =array[i];array[i] = array[j];array[j] = tmp;}

方法二:

//为了提高效率,可以左右一起找,找最小值放在前面,找最大值放在后面public static void selectSort2(int[] array){int left = 0;int right = array.length -1;while(left < right){int minIndex = left;int maxIndex = right;for(int j = left + 1;j <= right;j++){if(array[j] < array[minIndex]){minIndex = j;}if(array[j] > array[maxIndex]){maxIndex = j;}}//将最小值换到前面swap(array,minIndex,left);//如果max下标正好是Left说明上次已经把最大值从left位置换到了minIndex位置if(maxIndex == left){maxIndex = minIndex;}//吧最大值换到后面。swap(array,maxIndex,right);left++;right--;}}

选择排序的时间复杂度为:O(n^2)
空间复杂度:O(1)
稳定性:不稳定

2.2.3 堆排序

堆排序(Heapsort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。它是通过堆来进行选择数据。需要注意的是排升序要建大堆,排降序建小堆。
堆排序将要排序的数组创建成一个大根堆,再将第一个值和最后一个值进行交换,再将二叉树调整成为大根堆,依次循环排序。

//堆排序public static void heapSort(int[] array){creatBigHeap(array);int end = array.length -1;while(end > 0){swap(array,0,end);shiftDown(array,0,end);end--;}}private static void creatBigHeap(int[] array){for(int parent = (array.length - 1-1)/2;parent >= 0;parent--){shiftDown(array,parent,array.length);}}private static void shiftDown(int[] array,int parent,int len){int child = (2* parent) + 1;while(child < len){if(child+1 < len && array[child] < array[child+1]){child++;}if(array[child] > array[parent]){swap(array,child,parent);parent = child;child = 2 * parent +1;}else{break;}}}

堆排序的时间复杂度:O(N*logN)
在这里插入图片描述
空间复杂度:O(1)
稳定性:不稳定

2.3交换排序

基本思想:所谓交换,就是根据序列中两个记录键值的比较结果来对换这两个记录在序列中的位置,交换排序的特点是:将键值较大的记录向序列的尾部移动,键值较小的记录向序列的前部移动。

2.3.1冒泡排序

//冒泡排序public static void bubbleSort(int[] array){for(int i = 0;i < array.length;i++){boolean flg = false;for(int j = 0; j < array.length - 1-i;j++){if(array[j] > array[j+1]){swap(array,j,j+1);flg = true;}}if(flg == false){break;}}}

2.3.2快速排序

快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法,其基本思想为:任取待排序元素序列中的某元素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右子序列中所有元素均大于基准值,然后最左右子序列重复该过程,直到所有元素都排列在相应位置上为止。
1.Hoare排序
hoare排序是从右边开始找一个比key值小的,从左边找一个比key值大的数,两者进行交换,当left==right时,将此数与key交换。以此来排序。

//快速排序public static int partitionHoare(int[] array,int left,int right){int key = array[left];int i = left;while(left < right){while(left < right && array[right] >= key){right--;}while(left < right && array[left] <= key){left++;}swap(array,left,right);}swap(array,left,i);return left;}
  1. 挖坑法
    挖坑法就是以第一个数字为基准值,从右边找到一个比基准值大的数字放进基准的位置。再从左边找一个比基准值小的数字放进右边的位置
//挖坑法public static int partition2(int[] array,int left,int right){int key = array[left];while(left < right){while(left < right && array[right] >= array[key]){right--;}array[left] = array[right];while(left < right && array[left] <= array[right]){left++;}array[right] = array[left];}array[left] = key;return left;}
  1. 前后指针法
 //前后指针法private static int partition(int[] array, int left, int right) {int prev = left ;int cur = left+1;while (cur <= right) {if(array[cur] < array[left] && array[++prev] != array[cur]) {swap(array,cur,prev);}cur++;} swap(array,prev,left);return prev;}

在这里插入图片描述

2.3.2快速排序的优化

  1. 三数取中法选key
  2. 递归到小的子区间时,可以考虑使用插入排序
public static void insertSort(int[] array,int left,int right){for (int i = 1; i < array.length; i++) {int tmp = array[i];int j = i-1;for (;j >= 0;j--) {if(array[j] > tmp){array[j+1] = array[j];}else{break;}}array[j+1] = tmp;}}
public static void quick(int[] array,int start,int end){if(start >= end){return;}if(end - start + 1 <= 15){insertSort(array,start,end);return;}int index = findMidValIndex(array,start,end);swap(array,start,index);int key = partition(array,start,end);quick(array,start,key-1);quick(array,end,key+1);}public static int findMidValIndex(int[] array,int start,int end){int midIndex = (start + end)/2;if(array[start] > array[end]){if(array[midIndex] > array[start]){return start;} else if (array[midIndex] < array[end]) {return end;}else{return midIndex;}}else{if(array[midIndex] < array[start]){return start;} else if (array[midIndex] > array[end]) {return end;}else{return midIndex;}}}

2.3.3快速排序

  1. 快速排序整体的综合性能和使用场景都是比较好的,所以才敢叫快速排序
  2. 时间复杂度:O(N*logN)
  3. 空间复杂度:O(logN)
  4. 稳定性:不稳定

2.3.5非递归实现快速排序

在这里插入图片描述

先找基准
判断基准元素左边和右边是否有两个及以上元素?
如果有,则将首位置和p-1位置放入栈中(注意放入顺序)(处理左边),再将p+1位置和end位置放入栈中(处理右边)
当栈不为空的时候弹出两个元素在判断左边和右边的情况。依次循环

//非递归实现快速排序public static void quickSort(int[] array){Stack<Integer> stack = new Stack<>();int start = 0;int end = array.length-1;int pivot = partition(array,start,end);//1.判断左边是否有两个元素if(pivot > start + 1){stack.push(start);stack.push(pivot-1);}//2.判断右边是否有两个元素if(pivot < end-1){stack.push(pivot+1);stack.push(end);}while(!stack.isEmpty()){end = stack.pop();start = stack.pop();pivot = partition(array,start,end);//3.判断左边是否有两个元素if(pivot > start + 1){stack.push(start);stack.push(pivot-1);}//4.判断右边是否有两个元素if(pivot < end-1){stack.push(pivot+1);stack.push(end);}}}

2.4 归并排序

2.4.1递归实现归并排序

归并排序,首先要了解二叉树的基本知识,通过递归将数组分成一个一个的然后在合并。合并的时候可以参考前面写过的例题即两个有序数组合并问题。通过合并可以使数组有序,此时我们建立了新的数组。注意在最后给数组赋值的时候,tmpArr当中的数据是right left之间的有序数据。因此要从右侧开始。

在这里插入图片描述

public static void mergeSort1(int[] array){mergeSortChild(array,0,array.length-1);}private static void mergeSortChild(int[] array,int left,int right){if(left == right){return;}//拆分int mid = (left+right)/2;mergeSortChild(array,left,mid);mergeSortChild(array,mid+1,right);//合并merge(array,left,mid,right);}public static void merge(int[] array,int left,int mid,int right){int s1 = left;int e1 = mid;int s2 = mid +1;int e2 = right;int[] tmpArr = new int [right - left +1];int k = 0;while(s1 <= e1 && s2 <= e2){if(array[s1] <= array[s2]){tmpArr[k++] = array[s1++];}else{tmpArr[k++] = array[s2++];}}while(s1 <= e1){tmpArr[k++] = array[s1++];}while(s2 <= e2){tmpArr[k++] = array[s2++];}for(int i = 0;i < k;i++){array[i+left] = tmpArr[i];}}

由归并排序的思想可得,其
空间复杂度为:O(N)
时间复杂度为:O(N*logN)
稳定性:稳定
我们学过的稳定排序为:插入,冒泡,归并

2.4.2非递归的归并排序

非递归实现归并排序时,先将数组分成一个一个的,然后通过调整left,mid right来合并数组。
在这里插入图片描述

 //非递归实现归并排序public static void mergeSort(int[] array){int gap = 1;while(gap < array.length){for(int i = 0;i < array.length;i+=gap){int left = i;int mid = left + gap-1;int right = mid+gap;//需要考虑mid和right越界的问题,i在循环中,所以不用考虑i越界的问题if(mid >= array.length){mid = array.length -1;}if(right >= array.length){right = array.length-1;}merge(array,left,mid,right);}gap = 2*gap;}}

3.排序的总结

在这里插入图片描述

计数排序

在这里插入图片描述

public static void countSort(int[] array) {//1、遍历数组 找到 最小值 和最大值  -》 才能确定 计数数组的大小int maxVal = array[0];int minVal = array[0];//O(n)for (int i = 0; i < array.length; i++) {if(array[i] > maxVal) {maxVal = array[i];}if(array[i] < minVal) {minVal = array[i];}}//2、确定计数数组的长度int len = maxVal - minVal + 1 ;int[] countArr = new int[len];//3. 开始遍历 当前数组 统计每个数字出现的次数  O(n)for (int i = 0; i < array.length; i++) {int val = array[i];countArr[val-minVal] ++;//??????????????}int index = 0;//4. 遍历计数数组,看每个下标的值是几,就打印几个下标的数据就好了 O(范围 + n)//范围遍历一次,位置上所有的数的个数加起来等于nfor (int i = 0; i < countArr.length; i++) {while (countArr[i] > 0) {//不敢打印array[index] = i+minVal;//??????????????index++;countArr[i]--;}}}
http://www.mnyf.cn/news/16955.html

相关文章:

  • blog网站设计简单网页设计模板html
  • 做外贸的网站哪个好长沙seo服务
  • 深圳网站建设知了网络软件开发公司联系方式
  • 哪里建网站性价比高网站推广如何收费
  • php语言网站开发郑州seo竞价
  • 哪家做网站靠谱软文世界官网
  • 广东网站建设智搜宝网站代发外链
  • 贵阳seo技术整站seo技术搜索引擎优化
  • 关于网站开发的个人小结新开传奇网站发布站
  • 做车展招商的网站北京计算机培训机构前十名
  • 中国建设银行个人网上银行网站2019年度最火关键词
  • 平面设计师务所搜索引擎优化好做吗
  • 做网站哪个语言强班级优化大师的优点
  • 月嫂服务公司网站建设方案软件推广方案经典范文
  • 网站推广网站关键词排名怎么做百度推广登录官网
  • 温州做网站老师申请百度收录网址
  • 为什么做旅游网站深圳网络推广有几种方法
  • 网站设置高度百度网址大全首页链接
  • 邯郸启涵电子商务有限公司seo优化网络推广
  • 做.net网站流程seo怎么收费的
  • 做游戏网站需要多少钱it菜鸡网seo
  • wordpress网站怎么优化产品网络推广的方法
  • 淘宝网站开发语言如何开网站呢
  • 在门户网站做产品seoseo网络推广外包公司
  • 被墙网站怎么做301跳转友链外链app
  • 网站根目录在哪wordpress新网站如何快速收录
  • 烟台牟平住房建设局网站站长工具seo综合查询下载
  • 给别人做网站打电话推销看b站视频软件下载安装
  • 视频上到什么地方可以做网站链接来几个关键词兄弟们
  • 成都品牌设计网站今日头条10大新闻