1>冒泡
1》思想:它重复地走访过要排序的元素,依次比较相邻两个元素,如果他们的顺序错误就把他们调换过来,直到没有元素再需要交换,排序完成。
正序最快O(n)
反序最慢O(n^2)
2》算法步骤:
- 比较相邻的元素,如果前一个比后一个大,就把它们两个调换位置。
- 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
- 针对所有的元素重复以上的步骤,除了最后一个。
- 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
Js代码
function bubbleSort(arr){
var len=arr.length;
var temp;
for(var i=0;i<len;i++){
for(var j=0;j<len-1-i;j++){
if(arr[j]>arr[j+1]){
temp=arr[j+1];
arr[j+1]=arr[j];
arr[j]=temp;
}
}
}
return arr;
}
c代码
#include <stdio.h>
void bubble_sort(int a[], int n){
int i, j, temp;
for (j = 0; j < n - 1; j++)
for (i = 0; i < n - 1 - j; i++)
if(a[i] > a[i + 1])
{temp=a[i]; a[i]=a[i+1]; a[i+1]=temp;}
}
int main(){
int number[10] = {95, 45, 15, 78, 84, 51, 24, 12, 38, 97};
int i,SIZE=10;
bubble_sort(number, SIZE);
for (i = 0; i < SIZE; i++)
printf("%d", number[i]);
printf("\n");
}
- 插入排序
1》思想:每次从未排好的序列中选出第一个元素插入到已排好的序列中。 稳定
2》算法步骤可以大致归纳如下:
1. 从未排好的序列中拿出首元素,并把它赋值给temp变量;
2. 从排好的序列中,依次与temp进行比较,如果元素比temp大,则将元素后移(实际上放置temp的元素位置已经空出)
3. 直到找到一个元素比temp小, 将temp放入该位置;
时间复杂度:o(n^2)
Js代码
function insertSort(arr){
var len=arr.length;
var preIndex,current;
for(var i=1;i<len;i++){
preIndex=i-1;
current=arr[i];
while(preIndex>=0&&arr[preIndex]>current){
arr[preIndex+1]=arr[preIndex];
preIndex--;
}
arr[preIndex]=current;
}
return arr;
}
var arr=[3,1,5,7,2,4,9,6];
console.log(insertSort(arr));
C代码
void insertion_sort(int *a,int n)//a为数组,n为数组个数
{
int i,j,key;
for (j = 1;j < n;j++) {
key = a[j];
i = j - 1;
while (i >= 0 && a[i] > key) {
a[i+1] = a[i];
i--;
}
a[i+1] = key;
}
}
3>希尔排序
1》思想:将无序数组分割成若干子序列,子序列不是逐段分割的,而是相隔特定增量的子序列,对各个子序列进行插入排序,然后在选一个更小的增量,再将之前排序后的数组按这个增量分割成多个子序列,不断选择更小增量,直到增量为1,再对序列进行一次插入排序,使序列最终成为有序序列。
是插入排序一种更高效率的实现
Js代码
function shellSort(arr){
var len=arr.length;
var gap,temp;
for(gap=Math.floor(len/2);gap>0;gap=Math.floor(gap/2)){
for(var i=gap;i<len;i++){
var temp=arr[i];
for(var j=i-gap;j>=0&&arr[j]>temp;j-=gap){
arr[j+gap]=arr[j];
}
if(j!=i-gap){
arr[j+gap]=temp;
}
}
}
return arr;
}
var arr=[30,80,49,70,65,20,44,33,56,96]
console.log(shellSort(arr));
4>选择排序(时间复杂度上表现最稳定的排序算法之一,不论数据怎么放进去的时间复杂度是O(N^2))
1》思想:它的工作原理是每一次从无序组的数据元素中选出最小(或最大)的一个元素,存放在无序组的起始位置,无序组元素减少,有序组元素增加,直到全部待排序的数据元素排完。
2》算法步骤:
Js代码
function selectionSotr(arr){
var temp;
var minindex;
for(var i=0,len=arr.length;i<len-1;i++){
minindex=i;
for(var j=i+1;j<len;j++){
if(arr[minindex]>arr[j]){
minindex=j;
}
}
temp=arr[i];
arr[i]=arr[minindex];
arr[minindex]=temp;
}
return arr;
}
C代码
#include<stdio.h>
void SelectionSort(int *num,int n)
{
int i = 0;
int min = 0;
int j = 0;
int tmp = 0;
for(i = 0;i < n-1;i++)
{
min = i;//每次讲min置成无序组起始位置元素下标
for(j = i;j < n;j++)//遍历无序组,找到最小元素。
{
if(num[min]>num[j])
{
min = j;
}
}
if(min != i)//如果最小元素不是无序组起始位置元素,则与起始元素交换位置
{
tmp = num[min];
num[min] = num[i];
num[i] = tmp;
}
}
}
5>快排
1》思想:挖坑填数+分治法,先从数列中取出一个数作为基准数。分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。再对左右区间重复第二步,直到各区间只有一个数。
最坏情况O(n^2),顺序排序,处理大数据快
2》过程:
- 把数组的第一个作为基准点,数组第一个为low,最后一个是height。Height比基准点大,height--,height比基准点小,交换low,height,然后比较low与基准的大小,low比基准点小,low++,low比基准点大,交换low,height继续比较。
Js代码
function quickSort(arr){
if(arr.length<=1){
return arr;
}
var minindex=Math.floor(arr.length/2);
var minvalue=arr.splice(minindex,1);
var left=[];
var right=[];
for(var i=0;i<arr.length;i++){
if(minvalue>arr[i]){
left.push(arr[i]);
}else{
right.push(arr[i]);
}
}
return quickSort(left).concat(minvalue,quickSort(right));
}
c代码
#include<stdio.h>
#include <iostream>
using namespace std;
int AdjustArrays(int a[] ,int l ,int r )
{
int i =l,j=r;
int x=a[l];
while(l<r)
{
while(a[i]<=x&&i<j) j--;
a[i]=a[j];
i++;
while(a[j]>x&&i<j){i++; }
a[j]=a[i];
j--;
}
a[i]=x;
return i;
}
void QuickSort(int a[],int l,int r)
{
if(l<r)
{
int m=AdjustArrays(a,l,r);
AdjustArrays(a,0,m-1);
AdjustArrays(a,m+1,r);
}
}
int main()
{
int a[8]={3,2,5,8,6,7,6,9};
QuickSort(a,0,7);
for(int i=0;i<8;i++)
{
printf("%d\n",a[i]);
}
printf("%d\n",a[1]);
return 0;
}
6>堆排序
1》堆的基本概念:
大根堆:父节点键值总是大于或等于任何一个子节点,每个节点的子节点都是一个二叉堆,顶最大。
小根堆:顶最小
i节点的父节点下标(i-1)/2,它的左右子节点为2*i+1,2*i+2
2》思想:将代排序序列构成一个大根堆,将其与尾元素进行交换砍掉最后一个元素,将剩下的n-1个元素重新构成一个堆。
#include<stdio.h>
#define N 8
void Make_A_Heap(int a[],int end)
{
int tag,pa,t;
while(1)
{
pa=end/2;
tag=0;
while(pa)
{
if(a[pa]<a[pa*2]){
t =a[pa];
a[pa]=a[pa*2];
a[pa*2]=t;
tag=1;
}
if((pa*2+1)<=end&&a[pa]<a[pa*2+1])
{
t=a[pa];
a[pa]=a[pa*2+1];
a[pa*2+1]=t;
tag=1;
}
pa--;
}
if(!tag)
break;
}
}
void HeapSort(int a[]){
int end=N;
while(end>1)
{
//调整为大根堆
Make_A_Heap(a,end);
//交换
int t=a[1];
a[1]=a[end];
a[end]=t;
//砍掉
end--;
}
}
int main(void)
{
int a[N+1]={0,3,2,5,8,4,7,6,9};
HeapSort(a);
for(int i=1;i<N+1;i++)
{
printf("%d",a[i]);
}
return 0;
}
7>.归并排序
1》思想:采用分治法,将大问题分割成小问题。然后将小问题解决就解决了大问题。
将一个原始序列对等分为两部分,然后不断对等分新序列,直至序列的长度为1,如果一个序列为1,它本身就是之最,两个就直接比较,把比较之后的值推送到一个新的数组
两两归并,四四归并,八八归并
Js代码
function mergeSort(arr){
var len=arr.length;
if(len<2){
return arr;
}
var middle=Math.floor(len/2),
left=arr.slice(0,middle),
right=arr.slice(middle);
return merge(arguments.callee(left),arguments.callee(right));
}
function merge(left,right){
var result=[];
while(left.length>0&&right.length>0){
if(left[0]<right[0]){
result.push(left.shift());
}else{
result.push(right.shift())
}
}
while(left.length){
result.push(left.shift());
}
while(right.length){
result.push(right.shift());
}
return result
}
var arr=[3,44,5,47,15,36];
console.log(mergeSort(arr));
c代码
#include <stdio.h>
void Merge(int a[],int start,int end)
{
int mid=(start+end)/2;
int b[end-start];
int i,j,k;
i=start;
j=mid;
k=0;
while(i<mid||j<end)
{
//1、i没完 j完了
//2、i j都没完 但是a[i]<a[j]
if(j==end||i<mid&&a[i]<a[j]) //i<mid 是“i完了j没完时加的条件”
b[k++]=a[i++];
//1、i完了 j没完
//2、i j都没完 但是a[i]<a[j]不成立
else
b[k++]=a[j++];
}
//copy back
for(i=start,j=0;j<k;)
a[i++]=b[j++];
}
void MergeSort(int a[],int left,int right)
{
//保证元素个数>1
if(right-left>1)
{
int mid=(right+left)/2;
MergeSort(a,left,mid);
MergeSort(a,mid,right);
Merge(a,left,right);
}
}
8>基数排序
1》思想:将元素进行“分类”,把数字按照个位进行比较,然后再按照十位进行比较。