【数据结构】——八大排序

2023-11-18


在这里插入图片描述

1.插入排序

void InsertSort(int* a, int n)
{
    //i的最大下标为n-2,
    for(int i=0;i<n-1;i++)
    {
        //下标为end+1的元素是每次循环需要排序的元素
    	int end=i;
    	int tmp=a[end+1];
    	while(end>=0)
    	{
        	if(tmp<a[end])
        	{
            	a[end+1]=a[end];
            	--end;
        	}
        	else
        	{
            	break;
        	}
    	}
    	a[end+1]=tmp;
    }
}

时间复杂度:O(n^2)

2.冒泡排序

void Swap(int* pa, int* pb)
{
	int tmp = *pa;
	*pa = *pb;
	*pb = tmp;
}

void BubbleSort(int* a, int n)
{
	for (int j = 0; j < n; ++j)
	{
		int exchange = 0;
		// 单趟
		for (int i = 1; i < n-j; ++i)
		{
			if (a[i - 1] > a[i])
			{
				exchange = 1;
				Swap(&a[i - 1], &a[i]);
			}
		}

		if (exchange == 0)
		{
			break;
		}
	}
}

时间复杂度:O(n^2)

3.希尔排序

image-20220416092039674

特点

gap越小,越有序

gap越大,最大多数越在后面,越小的数越在前面,但是越无序

3.1一般希尔排序

void ShellSort(int*a,int n)
{
    for(int j=0;j<gap;j++)
    {
        //步长为gap
        for(int i=j;i<n-gap;i+=gap)
        {
            //单躺希尔排序
            int i=end;
            int tmp=a[end+gap];
            while(end>=0)
            {
                if(tmp<a[end])
                {
                    a[end+gap]=a[end];
                    end-=gap;
                }
                else
                {
                    break;
                }
            }
            a[end+gap]=tmp;-
        }
    }
}

3.2改进的希尔排序

多组同时进行预排序

void ShellSort(int*a,int n)
{
    int gap=n;
    while(gap>1)
    {
        gap=gap/3+1;
        //多组同时进行预排序
        for(int i=0;i<n-gap;i++)
        {
            int end=i;
            int tmp=a[end+gap];
            while(end>=0)
            {
                if(tmp<a[end])
                {
                    a[end+gap]=a[end];
                    end-=gap;
                }
                else
                {
                    break;
                }
            }
            a[end+gap]=tmp;
        }
    }
}

4.选择排序

void SelectSort(int*a,int n)
{
    int left=0,right=n-1;
    while(left<right)
    {
        int mini=left,maxi=left;
        for(int i=left+1;i<=right;i++)
        {
            if(a[i]<a[mini]) mini=i;
            if(a[i]>a[maxi]) maxi=i;
        }
        Swap(&a[mini],&a[left]);
        if(maxi==left)
        {
            maxi=mini;
        }
        Swap(&a[maxi],&a[right]);
        left++;
        right--;
    }
}

5.快速排序

算法实现:

​ 左边做key,就右边先走

​ 右边做key,就左边先走

进行单趟排序image-20220416213211213

image-20220416213245986

//先进行每一趟的排序
int PartSort1(int*a,int left,int right)
{
    int key=left;
    while(left<right)
    {
        //右边先走
        while(left<right&&a[right]>=a[key]) right--;
        while(left<right&&a[left]<=a[key]) left++;
        Swap(&a[left],&a[right]);
    }
    Swap(&a[key],&a[left]);
    return left;
}

hoare递归快排

//模板一
void QuickSort(int*a,int begin,int end)
{
    if(begin>=end)
        	return ;
    //返回中间的值
    int key=PartSort1(a,begin,end);
    QuickSort(a,0,key-1);
    QuickSort(a,key+1,end-1);
}
//模板二
void quick_sort(int q[], int l, int r)
{
    if (l >= r) return;

    int i = l - 1, j = r + 1, x = q[l + r >> 1];
    while (i < j)
    {
        do i ++ ; while (q[i] < x);
        do j -- ; while (q[j] > x);
        if (i < j) swap(q[i], q[j]);
    }
    quick_sort(q, l, j), quick_sort(q, j + 1, r);
}

挖坑法递归版image-20220418192540108

int PartSort2(int*a,int left,int right)
{
    int key=a[left];
    int pit=left;
    while(left<right)
    {
        //先走右边
        while(left<right&&a[right]>=key) right--;
        a[pit]=a[right];
        pit=right;
        while(left<right&&a[left]>=key) left++;
        a[pit]=a[left];
        pit=left;
    }
    a[pit]=key;
    return pit;
}
void QuickSort(int*a,int begin,int end)
{
    if(begin>=end)
        	return ;
    //返回中间的值
    int key=PartSort2(a,begin,end);
    QuickSort(a,0,key-1);
    QuickSort(a,key+1,end-1);
}

前后指针法image-20220418195506700

int PartSort3(int* a, int left, int right)
{
	int keyi = left;
	int prev = left, cur = prev + 1;
	while (cur<=right)
	{
        //遇见比自己小的就交换,同时避免不必要的交换
		if (a[cur] <a[keyi]&&a[++prev]!=a[cur])
			swap(&a[cur], &a[prev]);
		cur++;
	}
	swap(&a[prev], &a[keyi]);
	return prev;
}
void QuickSort(int*a,int begin,int end)
{
    if(begin>=end)
        	return ;
    //返回中间的值
    int key=PartSort3(a,begin,end);
    QuickSort3(a,0,key-1);
    QuickSort3(a,key+1,end-1);
}

快排的时间复杂度image-20220418224448335

每次选出的key都是最大或最小,那么最坏的时间复杂度就是O(N^2)

快排优化

1.三数取中优化image-20220418224514206

int GetMidIndex(int*a,int left,int right)
{
    int mid=left+(right-left)/2;
    if(a[left]>a[mid])
    {
        if(a[mid]<a[right]) return mid;
        else if(a[left]>a[right]) return left;
        else return right;
    }
    else
    {
        if(a[mid]>a[right]) return mid;
        else if(a[left]<a[right]) return left;
        else return right;
    }
}

对于前后指针法的三数取中的优化法

int PartSort3(int* a, int left, int right)
{
    int mid=GetMidIndex(a,left,right);
    Swap(&a[mid],a[left]);
	int keyi = left;
	int prev = left, cur = prev + 1;
	while (cur<=right)
	{
        //遇见比自己小的就交换,同时避免不必要的交换
		if (a[cur] <a[keyi]&&a[++prev]!=a[cur])
			swap(&a[cur], &a[prev]);
		cur++;
	}
	swap(&a[prev], &a[keyi]);
	return prev;
}
void QuickSort(int*a,int begin,int end)
{
    if(begin>=end)
        	return ;
    //返回中间的值
    int key=PartSort3(a,begin,end);
    QuickSort3(a,0,key-1);
    QuickSort3(a,key+1,end-1);
}

2.小区间优化

在区间较小的时候,可以使用插入排序

int PartSort3(int* a, int left, int right)
{
	int keyi = left;
	int prev = left, cur = prev + 1;
	while (cur<=right)
	{
        //遇见比自己小的就交换,同时避免不必要的交换
		if (a[cur] <a[keyi]&&a[++prev]!=a[cur])
			swap(&a[cur], &a[prev]);
		cur++;
	}
	swap(&a[prev], &a[keyi]);
	return prev;
}
void QuickSort(int*a,int begin,int end)
{
    if(begin>=end)
        	return ;
    //返回中间的值
    if(end-begin+1<=13)
    {
        InsertSort(a+begin,end-begin+1)
    }
    else
    {
        int key=PartSort3(a,begin,end);
    	QuickSort(a,0,key-1);
    	QuickSort(a,key+1,end-1);   
    }
}
递归改非递归
//递归在栈区调用,容易出现爆栈的风险,所以使用数据结构栈改为非递归
//使用栈,在堆上面开辟空间

void QuickSortNonR(int* a, int left, int right)
{
	Stack st;
	StackInit(&st);
	StackPush(&st, left);
	StackPush(&st, right);
	while (StackEmpty(&st) != 0)
	{
		right = StackTop(&st);
		StackPop(&st);
		left = StackTop(&st);
		StackPop(&st);
		int div = PartSort(a, left, right);
        if(left<div-1)
        {
            StackPush(&st, left);
            StackPush(&st, div-1);
        }
        if(div+1<right)
        {
            StackPush(&st, div+1);
            StackPush(&st, right);
        }
	}
	StackDestroy(&st)
}

用队列实现非递归快排

void QuickSortNonR(int* a, int left, int right)
{
	Queue qu;
    QueueInsert(&qu);
    QueuePush(&qu,left);
    QueuePush(&qu,right);
   	while(QueueEmpyt(&qu)!=0)
    {
        int left=QueueFront(&qu);
        QueuePop(&qu);
        int right=QueueFront(&qu);
        QueuePop(&qu);
        int keyi=PartSort(a,left,right);
        if(left<keyi-1)
        {
            QueuePush(&qu,left);
            QueuePush(&qu,keyi-1);
        }
        if(keyi+1<right)
        {
            QueuePush(&qu,keyi+1);
            QueuuPush(&qu,end);
        }
    }
    QueueDestory(&qu);
}

6.堆排序

步骤一:向下调整法

void AdjustDown(int* a, size_t size, size_t root)
{
    size_t parent=root;
    //假设需要交换的是左孩子
    size_t child=parent*2+1;
    while(child<size)
    {
        //如果右孩子存在且比右孩子小
        if(child+1<size&&a[child+1]<a[child])
        {
            child++;
        }
        if(a[child]>a[parent])
        {
            Swap(&a[child],&a[parent]);
            parent=child;
            child=parent*2+1;
        }
        else
        {
            break;
        }
    }
}

步骤二

void HeapSort(int*a,int n)
{
    //先建堆,从最后一个元素的parent开始,最后一层的结点本来就是堆,所以不用进行排序
    
    //建立大堆
    for(int i=(n-1-1)/2;i>=0;i--)
    {
        //向下调整
       AdjustDown(a,n,i);
    }
    size_t end=n-1;
    while(end>0)
    {
        Swap(&a[0],&a[end]);
        AdjustDown(a,end,0);
        end--;
    }
}

7.归并排序

递归归并排序

image-20220421142946088

void _MergeSortNonR(int* a, int begin,int end,int*tmp)
{
    if(begin>=end)
    	return ;
    int mid=(begin+end)/2;
    //如果不按照[begin,mid][mid+1,end]的方式划分,可能会出现死循环
     _MergeSortNonR(a,begin,mid,tmp);
     _MergeSortNonR(a,mid+1,end,tmp);
    //对已经排好序的两个区间进行归并排序
    int begin1=begin,end1=mid;
    int begin2=mid+1,end2=end;
    int index=begin;
    while(begin1<=end1&&begin2<=end2)
    {
        if(a[begin1]<a[begin2])
            tmp[index++]=a[begin1++];
        else
            tmp[index++]=a[begin2++];
    }
    while(begin1<=end1)
        tmp[index++]=a[begin1++];
    while(begin2<=end2)
        tmp[index++]=a[begin2++];
    memcpy(a+begin,tmp+begin,(end-begin+1)*sizeof(int));
}
void MergeSortNonR(int* a, int n)
{
    int*tmp=(int*)malloc(sizeof(int)*n);
    assert(tmp);
    _MergeSortNonR(a,0,n-1,tmp);
    free(tmp);
}
改成非递归
//利用gap控制步长
void _MergeSortNonR(int*a,int begin.int end,int*tmp)
{
	int gap=1;
    while(gap<n)
    {
        for(int i=0;i<n;i+=gap*2)
        {
         	int begin1=i,end1=i+gap-1;
    	 	int begin2=i+gap,end2=i+gap*2-1;
    	 	int index=i;
            while(begin1<=end1&&begin2<=end2)
    		{
        		if(a[begin1]<a[begin2])
            		tmp[index++]=a[begin1++];
        		else
            		tmp[index++]=a[begin2++];
    		}
    		while(begin1<=end1)
        		tmp[index++]=a[begin1++];
    		while(begin2<=end2)
        		tmp[index++]=a[begin2++];
    		memcpy(a+begin,tmp+begin,(end-begin+1)*sizeof(int));
            gap=gap*2;
    }
}
void MergeSortNonR(int* a, int n)
{
    int*tmp=(int*)malloc(sizeof(int)*n);
    assert(tmp);
    _MergeSortNonR(a,0,n-1,tmp);
    free(tmp); 
}

越界的三种情况image-20220421152518025

如果只是把越界的边界改为n-1,有部分区间就会遍历多次,index++就会发生越界访问

对于这一组数来说,前面两组步长为4的组正常归并,得到的结果为[1,6,7,10],[2,3,4,9];如果只是把越界的部分修改为n-1。那么最后一组的归并元素的下标为[8,9],[9,9]。对区间[8,9]进行归并,得到的结果为[2,5]。此时的++index=10,而另一部分的区间被我们修正为了[9,9]。所以继续归并一个数5,++index=11,发生越界访问。

因此,对于三种不同的越界情况,需要进行不同的修正

  • 对于[begin1,end1]由于end1,导致的越界访问,直接把end1修正为n-1;
  • 对于[begin2,end2]由于begin2和end2都有越界的可能,所以分情况讨论
    • 如果begin2没有越界,而end2越界了,把end2修改为n-1即可
    • 如果begin2和end2都发生越界,就把该区间修改为一个不存在的区间
//利用gap控制步长
void _MergeSortNonR(int*a,int begin.int end,int*tmp)
{
	int gap=1;
    while(gap<n)
    {
        for(int i=0;i<n;i+=gap*2)
        {
         	int begin1=i,end1=i+gap-1;
    	 	int begin2=i+gap,end2=i+gap*2-1;
    	 	int index=i;
            while(begin1<=end1&&begin2<=end2)
    		{
        		if(a[begin1]<a[begin2])
            		tmp[index++]=a[begin1++];
        		else
            		tmp[index++]=a[begin2++];
    		}
            //设置条件断点
            //if(begin1==8 &&end1==9 &&begin2==9 &&end2==9)
            //{
                //打一个断点
                //int x=0;
            //}
            if(end1>end)
            {
                end1=n-1;
            }
            //如果begin2大于了end,那么这个区间就一定不存在
            if(begin2>end)
            {
                begin2=n;
                end2=n-1
            }
            if(end2>end)
            {
                end2=n-1
            }
    		while(begin1<=end1)
        		tmp[index++]=a[begin1++];
    		while(begin2<=end2)
        		tmp[index++]=a[begin2++];
    		memcpy(a+begin,tmp+begin,(end-begin+1)*sizeof(int));
            gap=gap*2;
    }
}
void MergeSortNonR(int* a, int n)
{
    int*tmp=(int*)malloc(sizeof(int)*n);
    assert(tmp);
    _MergeSortNonR(a,0,n-1,tmp);
    free(tmp); 
}

8.计数排序

void CounSort(int*a,int n)
{
    int max=a[0],min=a[0];
    for(int i=0;i<n;i++)
    {
        if(a[i]>max)
            max=a[i];
        if(a[i]<min)
            min=a[i];
    }
    //找到数据的范围
    int range=max-min+1;
    int*res=(int*)malloc(sizeof(int)*range);
    memset(res,0,sizeof(int)*res);
    for(int i=0;i<n;i++)
    {
       //计数器
        res[a[i]-min]++;
    }
    int index=0;
    for(int i=0;i<range;i++)
    {
        while(res[i]--)
        {
            a[index++]=i+min;
        }
    }
}

9.题目

题目1

image-20220418232342355

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hkdR8iFH-1650528948534)(C:/Users/%E5%88%98%E9%91%AB/AppData/Roaming/Typora/typora-user-images/image-20220418232440060.png)]

题目2image-20220419083004816

int* shortestToChar(char * s, char c, int* returnSize)
{
    int len=strlen(s);
    int*res=(int*)malloc(sizeof(int)*len);
    int prev=-len;
    //左向右遍历,找字符与左C的最近距离
    for(int i=0;i<len;i++)
    {
        if(s[i]==c)
        {
            prev=i;
        }
       res[i]=i-prev; 
    }
    //右向左遍历,找字符与右C的最近距离
    for(int i = prev-1;i>=0;i--)
    {
        if(s[i] == c)
        {
            prev = i;
        }
        if(res[i] > prev-i)
        {
            res[i] =  prev-i;
        }
    }
    *returnSize=len;
    return res;
}
总结:排序的时间检验
void TestOP()
{
	srand(time(0));
	const int N = 1000000;
	int* a1 = (int*)malloc(sizeof(int) * N);
	int* a2 = (int*)malloc(sizeof(int) * N);
	int* a3 = (int*)malloc(sizeof(int) * N);
	int* a4 = (int*)malloc(sizeof(int) * N);
	int* a5 = (int*)malloc(sizeof(int) * N);
	int* a6 = (int*)malloc(sizeof(int) * N);
	int* a7 = (int*)malloc(sizeof(int) * N);

	for (int i = 0; i < N; ++i)
	{
		a1[i] = rand();
		a2[i] = a1[i];
		a3[i] = a1[i];
		a4[i] = a1[i];
		a5[i] = a1[i];
		a6[i] = a1[i];
		a7[i] = a1[i];
	}

	int begin1 = clock();
	//InsertSort(a1, N);
	int end1 = clock();

	int begin2 = clock();
	//ShellSort(a2, N);
	int end2 = clock();

	int begin7 = clock();
	//BubbleSort(a7, N);
	int end7 = clock();

	int begin3 = clock();
	//SelectSort(a3, N);
	int end3 = clock();

	int begin4 = clock();
	//HeapSort(a4, N);
	int end4 = clock();

	int begin5 = clock();
	QuickSort1(a5, 0, N - 1);
	int end5 = clock();

	int begin6 = clock();
	QuickSort2(a6, 0, N - 1);
	int end6 = clock();

	printf("InsertSort:%d\n", end1 - begin1);
	printf("ShellSort:%d\n", end2 - begin2);
	printf("BublleSort:%d\n", end7 - begin7);

	printf("SelectSort:%d\n", end3 - begin3);
	printf("HeapSort:%d\n", end4 - begin4);
	printf("QuickSort1:%d\n", end5 - begin5);
	printf("QuickSort2:%d\n", end6 - begin6);

	free(a1);
	free(a2);
	free(a3);
	free(a4);
	free(a5);
	free(a6);
	free(a7);
}
对于不同排序的时间复杂度分析

排序的稳定性

image-20220423111811005
八大排序的时间复杂度image-20220423142255396

  • 冒泡排序

    • 最好的情况:数组已经是有序,那么遍历一遍后就可以,时间复杂度是O(N)
    • 最坏的情况:数组每一次都需要交换,那么时间复杂度是O(N^2)
  • 选择排序

    • 无论数组的情况是怎么样的,每次遍历都需要找到最小然后交换,所以时间复杂度为O(N^2)
  • 插入排序

    • 最好的情况:数组完全有序,遍历数组就可以了,时间复杂度为O(N)
    • 最坏的情况:每次需要排序的数组都要交换到最前面的位置,比如完全逆序,时间复杂度为O(N^2)
  • 希尔排序

    • 最好的情况:类似于插入排序,但是由于gap,需要gap增长到gap=n,所以最好情况下的复杂度为O(N*logN)

    • 最坏的情况:类似于插入排序,每次都需要交换到最前面,时间复杂度为O(N^2)

  • 堆排序

    • 无论什么情况都需要建堆,堆排序的过程。所以时间复杂度为O(N*logN)
  • 归并排序

    • 归并排序满足完全的二分,所以时间复杂度为O(N^logN)
  • 快速排序

    • 最好情况:每次子快速排序都能将数组分为左右两个区间,所以时间复杂度为O(N*logN)

    • 最坏情况:数组完全有序,比如[1,2,3,4,5,6,7,8,9]。第一次排序结果为[1],[2,3,4,5,6,7,8,9]。以后的每一次子快排都将第一个数排好。所以时间复杂度为O(N^2)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【数据结构】——八大排序 的相关文章

  • 剑指offer(简单)

    目录 数组中重复的数字 替换空格 从尾到头打印链表 用两个栈实现队列 斐波那契数列 青蛙跳台阶问题 旋转数组的最小数字 二进制中的1的个数 打印从1到最大的n位数 删除链表的节点 调整数组顺序使奇数位于偶数前面 链表中倒数第k个节点 反转链
  • 剑指 Offer 53 - I. 在排序数组中查找数字 I

    剑指 Offer 53 I 在排序数组中查找数字 I 题目 题目链接 具体代码 题目 题目链接 https leetcode cn com problems zai pai xu shu zu zhong cha zhao shu zi l
  • 堆排序(Heapsort)-- 高级排序算法

    1 堆排序 Heapsort 堆排序 Heapsort 是指利用堆这种数据结构所设计的一种排序算法 二叉堆本质上是一种完全二叉树 它分为两个类型 最大堆和最小堆 最大堆任何一个父节点的值 都大于等于它左右孩子节点的值 最小堆任何一个父节点的
  • 快速排序————非递归实现

    二 递归实现快速排序 2 1 为什么我们要去通过递归实现我们的快速排序呢 大家有可能会想是不是因为递归非常的占用空间 我们都知道我们的局部变量是保存在栈上的我们的函数参数也是在栈上开辟的 所以说递归是不是会占用我们非常多的栈空间 同时呢我们
  • 数据结构之快速排序算法

    文章目录 快速排序的思想 快速排序的递归实现 快速排序的非递归实现 快速排序的思想 设置两个变量i j 排序开始的时候 令i 0 j length 1 以第一个数组元素作为比较 赋值给temp 即temp nums 0 从j开始向前扫描 找
  • C语言:二分查找(折半查找),冒泡排序

    目录 一 二分查找 二分查找的需注意的细节 二 冒泡排序 冒泡排序需注意的细节 本篇博客详细讲解常用的几个方法 分别是二分查找和冒泡排序法 一 二分查找 二分查找 意思就是每次都分为两部分 将查找的数字和中间数字相比 判断大小后确定所查找数
  • 8-13外部排序-败者树

    败者树是树形选择排序的一种变体 可视为一棵完全二叉树 通过败者树 可以在k个归并段中选出最小关键字所需要的关键字对比次数更少 绿色为叶子结点 存放初始数据 黑色为失败结点 蓝色为胜出结点 一 基本过程 以下按从小到大的方式构建 1 从8个归
  • 【Java】5大排序算法总结(插入排序+希尔排序+选择排序+堆排序+冒泡排序)

    快速导航 1 稳定性 2 插入排序 3 希尔排序 4 选择排序 5 堆排序 6 冒泡排序 1 稳定性 两个相等的数据 如果经过排序后 排序算法能保证其相对位置不发生变化 则我们称该算法是具备稳定性的排序算法 图中排序后a仍然在b前面 此时这
  • 堆排序(堆的构造及代码实现)

    简介 java系列技术分享 持续更新中 初衷 一起学习 一起进步 坚持不懈 如果文章内容有误与您的想法不一致 欢迎大家在评论区指正 希望这篇文章对你有所帮助 欢迎点赞 收藏 留言 更多文章请点击 文章目录 一 堆的简介 二 堆的实现 2 1
  • 【华为OD机试真题 python】 字符统计及重排【2022 Q4

    前言 华为OD笔试真题 python 专栏含华为OD机试真题 华为面试题 牛客网华为专栏真题 如果您正在准备华为的面试 或者华为od的机会 有任何想了解的可以私信我进行交流 我会尽可能的给一些建议 和帮您解答 题目描述 字符统计及重排 给出
  • 【数据结构与算法】--排序

    目录 一 排序的概念及其运用 二 常见的排序算法 2 2选择排序 2 3 交换排序 2 3 4 1 快速排序优化 一 排序的概念及其运用 1 1 排序的概念 排序 所谓排序 就是使一串记录 按照其中的某个或某些关键字的大小 递增或递减的排列
  • 插入排序总结

    插入排序 Insertion Sort 的算法描述是一种简单直观的排序算法 它的工作原理是通过构建有序序列 对于未排序数据 在已排序序列中从后向前扫描 找到相应位置并插入 排序思路 假设按照升序排序 1 从索引为1的元素开始向前比较 一旦前
  • C++容器排序算法的简单应用

    功能实现 1 去掉所有重复的单词 2 按照单词的长度进行排序 3 统计长度等于或者超过6个字符的单词个数 4 按照单词的长度顺序进行输出 include
  • 数据结构——排序算法——基数排序

    基数排序有两种实现方式 本例属于最高位优先法 思路是从最高位开始 依次对基数进行排序 与之对应的是 最低位优先法 思路是从最低位开始 依次对基数进行排序 基数排序可以分为以下三个步骤 1 找到数组中的最大值 确定最大数字的位数 2 从最低位
  • GIF演示排序算法

    最近在准备笔试 面试 看了不少关于排序算法的知识 总感觉代码有余 直观不足 所以想利用直观的GIF动图来演示各种排序算法 1 插入排序 Insertion Sort 1 1算法简介 插入排序 Insertion Sort 的算法描述是一种简
  • 如何学好C语言的数据结构与算法?

    C语言的数据结构与算法 难就难在链表 学会了链表 可能后面就一点都不难了 书籍推荐 数据结构与算法分析 C语言描述版 要深入学习的话可以选择这本书 因为针对链表的讲解是比较详细的 所以可以很快理解链表 跟着书上一点点实现基本操作 增删改查
  • C#冒泡排序算法

    冒泡排序实现原理 冒泡排序是一种简单的排序算法 其原理如下 从待排序的数组的第一个元素开始 依次比较相邻的两个元素 如果前面的元素大于后面的元素 升序排序 则交换这两个元素的位置 使较大的元素 冒泡 到右侧 继续比较下一对相邻元素 重复步骤
  • C语言排序算法实现

    C语言实现各种排序算法 冒泡排序 选择排序 插入排序 希尔排序 插入方式 非交换方式 快速排序 归并排序 分治思想 基数排序 桶排序 基数排序的基本思想 典型的空间换时间方式 冒泡排序 include
  • 基数排序代码实现

    详情请看排序总结 传送门 https blog csdn net m0 52711790 article details 121914543 基数排序的知识点我就不贴出来 相信都能搜到对应概念解释 下面就直接上代码 代码解释其实也很清晰了
  • 详解十大经典排序算法(四):希尔排序(Shell Sort)

    算法原理 希尔排序是一种基于插入排序的排序算法 也被称为缩小增量排序 它通过将待排序的序列分割成若干个子序列 对每个子序列进行插入排序 然后逐步缩小增量 最终使整个序列有序 算法描述 希尔排序 Shell Sort 是一种基于插入排序的算法

随机推荐

  • 手机iCloud储存空间已满,怎么解决?

    最近手机总是弹出iCloud储存空间已满 升级的话得花钱 以后再说的话 总感觉有点 不安 担心自己的照片啥的会存不了 所以特意查找了这种方法 如果有出现这种情况的朋友 可以试试 1 找出iCloud空间被哪些档案塞满 iiPhone或iPa
  • Linux之mmv命令批量替换文件名(超详细-python结合mmv)

    文章目录 一 前言 二 各系统安装mmv方法 2 1 CentOS 2 2 Ubuntu And Debain 2 3 MacOS 三 使用方法 3 1 常规使用 3 1 1 常规使用示例 3 2 携带参数使用 3 2 1 携带参数使用示例
  • vue3.x之isRef toRefs isRef readonly 公共数据配置 axios配置 路由配置

    isRef toRefs toRef 参数 源对象 源对象属性 可以用来为源响应式对象上的某个 property 新创建一个 ref 然后 ref 可以被传递 它会保持对其源 property 的响应式连接 也就是说源响应式对象 toRef
  • 3427: Dark roads

    http cs scu edu cn soj problem action id 3427 Description Economic times these days are tough even in Byteland To reduce
  • 向量二范数的求导问题

    现有目标函数 f x 1 2
  • ant design pro 可编辑表格

    import React useRef from react import PageHeaderWrapper from ant design pro layout import ProColumns ActionType TableDro
  • python elif 用法,在Python列表推导中对if / elif语句使用'for'循环

    I am trying to translate this for loop into a list comprehension a 1 2 3 4 5 6 7 8 9 result for i in a if i lt 3 result
  • 数据结构--单链表的插入&删除

    数据结构 单链表的插入 删除 目标 单链表的插入 位插 前插 后插 单链表的删除 单链表的插入 按为序插入 带头结点 ListInsert L i e 插入操作 在表L中的第i个位置上插入指定元素e 思路 找到第i 1个结点 将新结点插入其
  • ElasticSearch学习:ElasticSearch概述

    elasticsearch用于文本搜索的函数库Lucene ElasticSearch是基于此做的封装和增强 ElasticSearch 简称es es是一个开源的高拓展的分布式全文检索引擎 它可以近乎实施的存储 检索数据 本身扩展性很好
  • python代码行末的 \ 符号

    mlm l loss mlm Y hat reshape 1 vocab size mlm Y reshape 1 mlm weights X reshape 1 1 在代码中 是Python中的行继续符号 它用于表示代码行在物理上被分成多
  • 如何开始使用 GitLab 的 CLI 从终端管理 DevOps

    GitLab是面向现代软件交付团队的领先源代码控制和 CI CD 解决方案之一 它提供了一整套用于规划 构建和交付软件项目的功能 GitLab 通常使用其 Web UI 或 API 进行交互 这些选项对于以终端为中心的开发人员来说都不是特别
  • 强化学习笔记(1)-同策回合更新算法

    在我上一篇博客文章https blog csdn net gzroy article details 119509552中对21点的策略进行了研究 采用蒙特卡洛的方式来进行多次的模拟 通过对比不同策略的收益来找到最佳的策略 主要是通过概率的
  • layui的分页实例详解

    原 layui的分页实例详解 2018年09月20日 17 43 07 李什么泽 阅读数 11571 更多 分类专栏 layui分页 版权声明 本文为博主原创文章 遵循 CC 4 0 BY SA 版权协议 转载请附上原文出处链接和本声明 本
  • ndk错误总结

    1 ndk Unresolved inclusion
  • mongo在linux下的安装(实践记录)

    1 下载安装包 wget http fastdl mongodb org linux mongodb linux i686 1 8 2 tgz 下载完成后解压缩压缩包 tar zxf mongodb linux i686 1 8 2 tgz
  • IDEA Cannot resolve plugin org.apache.maven.pluginsmaven-jar-plugin2.4

    起因 最近在弄Maven项目 在使用IDEA创建Maven项目得时候一直报错 搞的我很头疼 网上搜索答案 都是修改Setting xml 配置本地仓库 然后我测试了好多次都不管用 但是根据错误信息他的确是Maven仓库配置得问题和IDEA
  • 初识GoogleTest

    1 初识GoogleTest 首先要了解googletest是做什么的 主要是单元测试框架 第二是googletest有什么优势 测试过程独立可以重复 测试组织与代码结构保持比较好的一致性 支持跨平台 失败后能够提供完整错误信息 同时支持失
  • 来谈谈 BlockingQueue 阻塞队列实现类 java.util.concurrent.LinkedBlockingQueue(JDK1.8 源码分析)

    LinkedBlockingQueue源码刨析 文章目录 LinkedBlockingQueue源码刨析 前言 一 LinkedBlockingQueue源码部分 1 构造方法 2 成员变量 3 主要方法 1 入队操作 offer方法 pu
  • 毕设草稿保存

    这里写目录标题 参数大小 MobileViT xxs参数 MobileViT xs参数 MobileViT s参数 MobileViT SE模块 无SE模块时 有预训练文件 无预训练文件 有预训练文件且加SE模块之后 无预训练文件且加了SE
  • 【数据结构】——八大排序

    文章目录 1 插入排序 2 冒泡排序 3 希尔排序 4 选择排序 5 快速排序 快排优化 递归改非递归 6 堆排序 7 归并排序 递归归并排序 改成非递归 8 计数排序 9 题目 总结 排序的时间检验 对于不同排序的时间复杂度分析 1 插入