数据结构08--排序及查找

news2024/9/23 3:23:49

1.基本概念

        排序是处理数据的一种最常见的操作,所谓排序就是将数据按某字段规律排列,所谓的字段就是数据节点的其中一个属性。比如一个班级的学生,其字段就有学号、姓名、班级、分数等等,我们既可以针对学号排序,也可以针对分数排序。

  • 稳定性与非稳定性

稳定排序:排序前后两个相等的数相对位置不变,则算法稳定

非稳定排序:排序前后两个相等的数相对位置发生了变化,则算法不稳定

  • 内排序与外排序

如果待排序数据量不大,可以一次性全部装进内存进行处理,则称为内排序,若数据量大到无法一次性全部装进内存,而需要将数据暂存外存,分批次读入内存进行处理,则称为外排序。

性能分析

不同的排序算法性能不同,详细性能数据如下表所示。

排序算法

平均 T(n)

最坏 T(n)

最好 T(n)

空间复杂度

稳定性

选择排序

O(n2)

O(n2)

O(n2)

O(1)

不稳定

插入排序

O(n2)

O(n2)

O(n)

O(1)

稳定

希尔排序

O(n1.3)

O(n2)

O(n)

O(1)

不稳定

冒泡排序

O(n2)

O(n2)

O(n)

O(1)

稳定

快速排序

O(nlog2​n)

O(n2)

O(nlog2​n)

O(nlog2​n)

不稳定

从表中可以得到一些简单的指导思路:

  1. 选择排序、插入排序和冒泡排序思路简单,但时间效率较差,只适用于数据样本较小的场合,这几种算法的好处是不需要额外开辟空间,空间复杂度是常量。
  2. 希尔排序是插入排序的改进版,在平均情况下时间效率要比直接插入法好很多,也不需要额外开辟空间,要注意的是希尔排序是不稳定排序。
  3. 快速排序是所有排序算法中时间效率最高的,但由于快排是一种递归运算,对内存空间要求较高,当数据量较大时,会消耗较多的内存。

2. 插入排序

2.1思路

        插入排序的思路也很简单:假设前面已经有i节点是有序的(排好顺序),那么就从第i+1个节点开始,插入到前面的i个节点的合适的位置中。由于第一个元素自身总是有序的(假设性),因此从第2个开始,不断插入前面的有序序列,直到全部排列完毕。

        假设总共有n个节点,那么总共需要将n−1个节点插入到有序序列中,而插入节点时需要找到合适的位置,显然这个查找的过程时间复杂度是O(n−i),因此插入排序的时间复杂度是O(n−1)(n−i),即O(n2)

2.2 示例代码

// 插入排序
/**插入排序就是遍历每个元素,要插入的元素都往前面的有序元素遍历比较,如果被比较的
 * 元素比要插入的元素大,那就把大的元素往后挪(大的元素往后挪并且留一个空位插入)
 * 一直往前比较,直到前面的元素比插入的元素小,那就把元素插入到其之后
 * 设计思路:
 * 设计两个循环,外循环遍历每一个元素,遍历要插入排序的元素,接着内循环拿到要插入排序
 * 的元素,在前面已排序完成的元素进行插入排序。
 * 理解就是假如有n个元素,那总共有n-1个元素要排序,因为第一个元素总是有序的
 * 所以第一步设计for循环遍历每一个元素,将要插入的每个元素赋给一个临时变量,
 * 接着进入内循环,将临时变量的元素在前面已排序完成的元素进行比较,找到要插入的地方
 * 将要插入位置后面的元素向后挪再插入要插入的元素,或者直接插入要插入的元素,内循环结束
 * 成功插入排序一个元素,以此类推,外循环遍历完所有的元素,插入排序完成
 */
#include <stdio.h>
/// @brief 插入排序
/// @param arr 数组首元素地址
/// @param len 数组元素个数
void insertSort(int *arr, int len)
{
    int i, j, tmp;
    // 当数组只有一个元素时,无需排序
    if (len == 1)
    {
        return;
    }
    // 第一个元素无须排序
    // 从arr[1] 到arr[len - 1]
    for (i = 1; i < len; i++)
    {
        // 临时变量tmp拿到要插入排序的元素
        tmp = arr[i];
        // 在前面已排序完成的元素进行比较
        for (j = i - 1; j >= 0; j--)
        {
            // 找到合适位置即跳出循环
            if (arr[j] < tmp)
            {
                break;
            }
            else
            {
                // 元素向后挪,为插入元素挪出空位
                arr[j + 1] = arr[j];
            }
        }
        // 要插入的元素插入到合适位置中
        arr[j + 1] = tmp;
    }
}
int main(void)
{
    int i, len;
    int arr[6] = {0};
    // 计算元素个数
    len = sizeof(arr) / sizeof(int);
    printf("请输入%d个整数:", len);
    for (i = 0; i < len; i++)
    {
        scanf("%d", &arr[i]);
    }
    printf("排序前数据:");
    for (i = 0; i < len; i++)
    {
        printf("%d\t", arr[i]);
    }
    printf("\n");
    // 插入排序
    insertSort(arr, len);
    printf("排序后数据:");
    for (i = 0; i < len; i++)
    {
        printf("%d\t", arr[i]);
    }
    printf("\n");
    return 0;
}

代码运行结果:

2.3插入排序单向循环链表:

/// @brief 插入排序链表
/// @param head 链表头节点
void insertSort(P_node_t head)
{
    // 判断链表是否为空
    if (isListEmpty(head))
    {
        printf("链表为空.\n");
        return;
    }
    // outTmp外循环遍历链表每一个节点,inTmpPrev内循环遍历要插入节点之前的节点,inTmp为inTmpPrev后继节点
    // insertNode存放指向要插入的节点,insertNodePrev为插入节点的前驱节点
    P_node_t outTmp = NULL, inTmp = NULL, inTmpPrev = NULL, insertNode = NULL, insertNodePrev = NULL;
    // 外循环遍历链表从有效节点开始,所以outTmp初始条件为head->next
    // 当outTmp==head,outTmp遍历完整个链表,所以结束条件为outTmp!=head
    for (outTmp = head->next; outTmp != head;)
    {
        // insertNode存放指向要插入的节点
        insertNode = outTmp;
        // 内循环进行每个insertNode要插入节点的插入位置寻找
        // 插入需要前驱节点,所以初始条件从head头节点开始,结束条件为:遍历到要插入节点的前驱节点
        for (inTmpPrev = head; inTmpPrev->next != insertNode; inTmpPrev = inTmpPrev->next)
        {
            // inTmpPrev遍历到合适的插入位置跳出循环
            if (inTmpPrev->next->data.num > insertNode->data.num)
            {
                break;
            }
        }
        // 此时跳出循环,有两种情况:
        // 一是inTmpPrev遍历到要插入节点的前驱节点,即要插入节点前的链表都没有遍历到合适的位置插入
        if (inTmpPrev->next == insertNode)
        {
            // 更新outTmp往下遍历
            outTmp = outTmp->next;
            // 此时要插入的节点在合适的位置无需插入,continue提高插入排序效率
            continue;
        }
        // 插入前更新outTmp往下遍历
        outTmp = outTmp->next;
        // inTmp为inTmpPrev的后继节点
        inTmp = inTmpPrev->next;
        // 将insertNode节点插入前需要先将insertNode节点从链表中剔除下来,剔除insertNode节点需要用到其前驱节点
        for (insertNodePrev = head; insertNodePrev->next != insertNode; insertNodePrev = insertNodePrev->next)
            ;
        // 将insertNode从链表中剔除下来
        // insertNode前驱节点的next指针指向insertNode的后继节点
        insertNodePrev->next = insertNode->next;
        // insertNode的next指针指向自己,将insertNode节点从链表剔除下来
        insertNode->next = insertNode;
        // 将insertNode插入到链表中,即inTmp节点和inTmpPrev节点之间
        // insertNode的next指针指向inTmp
        insertNode->next = inTmp;
        // inTmpPrev的next指向insertNode
        inTmpPrev->next = insertNode;
    }
    return;
}

3.希尔排序

3.1. 希尔排序基本概念

1. 希尔排序的定义

        希尔排序,又称为“缩小增量排序”,是插入排序的一种改进版本。它通过比较相隔一定间隔的元素,交换不相邻的元素,以在每一轮中逐步将未排序的序列变得有序。希尔排序的核心思想是通过逐渐减小元素之间的间隔,使得序列在初始阶段就呈现局部有序,从而减少插入排序的工作量。

2缩小增量排序

        希尔排序的特点之一是采用了缩小增量的策略,即通过逐步减小间隔来进行排序。这种策略有助于将元素较远的部分先进行粗略排序,使得序列逐渐趋于整体有序。

3. 插入排序的变种

        希尔排序可以看作是插入排序的一种变种,但在插入排序的基础上增加了分组和间隔的概念,通过这种方式来改进插入排序的性能。

3.2. 希尔排序的工作原理

1 分组

希尔排序首先将待排序的元素分成若干组,每组包含间隔为 h 的元素,其中 h 称为增量。初始增量的选择是关键的,不同的增量序列会影响排序的效率。

2 插入排序

对每组元素进行插入排序,即对每个小组内的元素使用插入排序算法进行排序。这一步的目的是在每个小组内部实现局部有序。

3 逐步减小增量

重复上述步骤,逐步减小增量,每次减小都会对分组后的小组进行插入排序。最终,当增量减小至 1 时,整个序列已经基本有序,最后进行一次插入排序,完成整个排序过程。

希尔排序通过引入增量,使得排序的过程在开始阶段就能够更好地利用局部有序性,从而提高了效率。虽然希尔排序的性能受到增量序列选择的影响,但相比于简单的插入排序,它在大规模数据集上的性能表现通常更好。

3.3. 算法步骤

希尔排序的算法步骤可以概括为以下几个关键步骤:

1. 初始化增量序列

选择一个增量序列,该序列通常是递减的正整数序列。常用的增量序列有希尔建议的序列、Hibbard序列、Sedgewick序列等。增量序列的选择会直接影响希尔排序的性能。

初始化增量一般选的是:len/2;

2. 外层循环:逐步缩小增量

使用选定的增量序列进行外层循环,每次循环缩小增量。在每一轮外层循环中,通过增量对元素进行分组,每组包含相隔一定间隔的元素。这一步骤旨在逐步减小元素之间的间隔,从而实现序列的局部有序。

3. 内层循环:插入排序

在每一组内,通过插入排序对元素进行排序。这是希尔排序的关键步骤,通过比较相隔增量的元素,并在需要时交换它们的位置,逐步实现每个小组的局部有序。

4. 完成排序

重复外层循环和内层循环,逐渐减小增量,直到增量为 1。最后一次外层循环使用增量为 1,相当于进行一次标准的插入排序。此时,整个序列已经基本有序,最终完成排序。

通过这样的逐步优化,希尔排序在大规模数据集上能够比插入排序更快速地完成排序任务。希尔排序的性能和增量序列的选择密切相关,因此对于不同的应用场景可能需要选择不同的增量序列以达到更好的排序效果。

#include <stdio.h>
void shellSort(int arr[], int n) 
{
    //缩小增量,以长度8为例,增量变化:4  2  1
    for (int gap = n / 2; gap > 0; gap /= 2) 
    {
        //组内排序 元素arr[gap]到arr[n-1]
        for (int i = gap; i < n; i++)//
        {
                int temp = arr[i];
                int j;                 //arr[0]>arr[4]
                for (j = i; j >= gap && arr[j - gap] > temp; j -= gap)
                {
                        arr[j] = arr[j - gap];
                }
                arr[j] = temp;
        }
    }
}
int main(void)
{
    int i, len;
    int arr[8] = {0};
    //计算元素个数
    len = sizeof(arr)/sizeof(int);
    printf("请输入%d个整数:",len);
    for(i=0; i<len; i++)
    {
        scanf("%d", &arr[i]);
    }
    printf("排序前数据:");
    for(i=0; i<len; i++)
    {
        printf("%d\t", arr[i]);
    }   
    printf("\n");
    //希尔排序
    shellSort(arr, len);   
    printf("排序后数据:");
    for(i=0; i<len; i++)
    {
        printf("%d\t", arr[i]);
    }   
    printf("\n");
    return 0;
}

4.冒泡排序(重点掌握)

首先引入两个概念:

  • 顺序:如果两个数据的位置符合排序的需要,则称它们是顺序的。
  • 逆序:如果两个数据的位置不符合排序需要,则称它们是逆序的。

冒泡排序基于这样一种简单的思路:从头到尾让每两个相邻的元素进行比较,顺序就保持位置不变,逆序就交换位置。可以预料,经过一轮比较,序列中具有“极值”的数据,将被挪至序列的末端。

假如序列中有n个数据,那么在最极端的情况下,只需要经过n−1轮的比较,则一定可以将所有的数据排序完毕。冒泡法排序的时间复杂度是O(n2)

示例代码:

#include <stdio.h>
#if 0
void maopaoSort(int arr[], int n) 
{
    int i, j;
    //需要排序的数组次数
    for(i=0; i< (n-1); i++)
    {
        //数组内排序 5-1 = 4
        for(j=0; j < (n-i-1) ; j++)
        {
            if(arr[j] > arr[j+1])
            {
                //数据交换
                int tmp  = arr[j+1];
                arr[j+1] = arr[j];
                arr[j]   = tmp;
            }
        }       
    }
}
#else
void maopaoSort(int arr[], int n) 
{
    int i, j;
    //需要排序的数组次数
    for(i=(n-1); i > 0; i--)
    {
 
        for(j=0; j < i; j++)
        {
            if(arr[j] > arr[j+1])
            {
                //数据交换
                int tmp  = arr[j+1];
                arr[j+1] = arr[j];
                arr[j]   = tmp;
            }
        }       
    }
}
#endif
int main(void)
{
    int i, len;
    int arr[8] = {0};
    //计算元素个数
    len = sizeof(arr)/sizeof(int);
    printf("请输入%d个整数:",len);
    for(i=0; i<len; i++)
    {
        scanf("%d", &arr[i]);
    }
    printf("排序前数据:");
    for(i=0; i<len; i++)
    {
        printf("%d\t", arr[i]);
    }   
    printf("\n");
    //冒泡排序
    maopaoSort(arr, len);   
    printf("排序后数据:");
    for(i=0; i<len; i++)
    {
        printf("%d\t", arr[i]);
    }   
    printf("\n");
    return 0;
}

注意:

上述冒泡排序中,对算法做了优化,主要有两点:

1.由于每一趟比较后,都至少有1个“极值”被移至末端,因此第i趟比较只需n−i次

2.当发现某一趟比较中全部为顺序时,则意味着序列已经有序,则可以提前退出

5.选择排序

        选择排序的思路非常简单,就是依次从头到尾挑选合适的元素放到前面。如果总共有n个节点,那么选择一个合适的节点需要比较n次,而总共要选择n次,因此总的时间复杂度是O(n2)

下面以无序数组data为例,假设存储的是整型数据,让其从小到大排序,示例代码:

#include <stdio.h>

void paixu(int *p,int len);
void swap(int *a, int *b);
void display(int *arr, int len);

int main(void)
{
    int i, len;
    int arr[10];

    len = sizeof(arr)/sizeof(int);

    printf("请输入10个整数:\n");

    for(i=0; i<10; i++)
    {
        scanf("%d", &arr[i]);
    }

    printf("排序前数据:\n");

    display(arr, len);

    paixu(arr, len);

    printf("排序后数据:\n");

    display(arr, len);
}
//选择排序
void paixu(int *p,int len)
{
    int i, j, min;

    for(i=0; i<len; i++)
    {
        min = i;  //最小值下标
        for(j = i+1; j<len; j++)
        {
            if(p[j] < p[min]) //如果最p[j] 小于 p[min],要更换最小下标
            {
                min = j;
            }

        }
       swap(&p[i], &p[min]); 
    }
    return;
} 

void swap(int *a, int *b)
{

    int tmp;
    tmp = *a;
    *a = *b;
    *b = tmp;
}

void display(int *arr, int len)
{
    int i;
    for(i=0; i<len; i++)
    {
        printf("%d\t", arr[i]);
    }    
    printf("\n");
}

6.快速排序(重点掌握)

1.基本思路

快排是一种递归思想的排序算法,先比较其他的排序算法,它需要更多内存空间,但快排的语句频度是最低的,理论上时间效率是最高的。

快速排序的基本思路是:在待排序序列中随便选取一个数据,作为所谓“支点”,然后所有其他的数据与之比较,以从小到大排序为例,那么比支点小的统统放在其左边,比支点大的统统放在其右边,全部比完之后,支点将位与两个序列的中间,这叫做一次划分(partition)。

一次划分之后,序列内部也许是无序的,但是序列与支点三者之间,形成了一种基本的有序状态,接下去使用相同的思路,递归地对左右两边的子序列进行排序,直到子序列的长度小于等于1为止。

2. 示例代码:

#include <stdio.h>
void display(int *arr, int len)
{
    int i;
    for(i=0; i<len; i++)
    {
        printf("%d\t", arr[i]);
    }
    printf("\n");
}
void swap(int *a, int *b)
{
    int tmp;
    tmp = *a;
    *a = *b;
    *b = tmp;
}
//找支点
int partion(int *arr, int len)
{
    int i, j;
    if(len <= 1)
        return 0;
    i = 0; 
    j = len-1;
    while(i < j)
    {
        while(arr[i] < arr[j] && i<j)
        {
            j--;
        }
        swap(&arr[i], &arr[j]);
        while(arr[i] <= arr[j] && i<j)
        {
            i++;
        }
        swap(&arr[i], &arr[j]);
    }
  
    //返回支点
    return i;
}
//快速排序
void quickSort(int arr[],int len)
{
    if(len <= 1)
        return;
    
    //找支点
    int pivort=partion(arr, len);
    //左边
    quickSort(arr, pivort); 
    //右边
    quickSort(arr+pivort+1, len-pivort-1); 
} 
int main(void)
{
    int i, len;
    int arr[6] = {0};
    //计算元素个数
    len = sizeof(arr)/sizeof(int);
    printf("请输入%d个整数:",len);
    for(i=0; i<len; i++)
    {
        scanf("%d", &arr[i]);
    }
    printf("排序前数据:");
    for(i=0; i<len; i++)
    {
        printf("%d\t", arr[i]);
    }   
    printf("\n");
    //快速排序
    quickSort(arr, len);   
    printf("排序后数据:");
    for(i=0; i<len; i++)
    {
        printf("%d\t", arr[i]);
    }   
    printf("\n");
    return 0;
}

7.二分法查找(要求数据有序)

        二分査找也称折半査找,其优点是查找速度快,缺点是要求所要査找的数据必须是有序序列。该算法的基本思想是将所要査找的序列的中间位置的数据与所要査找的元素进行比较,如果相等,则表示査找成功,否则将以该位置为基准将所要査找的序列分为左右两部分。接下来根据所要査找序列的升降序规律及中间元素与所查找元素的大小关系,来选择所要査找元素可能存在的那部分序列,对其采用同样的方法进行査找,直至能够确定所要查找的元素是否存在,具体的使用方法可通过下面的代码具体了解。

#include <stdio.h>
//返回元素下标
int  binarySearch(int a[], int n, int key)
{
    //数组下标
    int low = 0;
    int high = n-1;
    int midval;
    int mid = 0;
    while(low <= high)
    {
        mid = (low+high)/2;
        midval = a[mid];
        if(midval == key)
            return mid;
        if(midval < key)
        {
            low = mid+1;
        }
        else
        {
            high = mid-1;
        }
        
    }
    return -1;
}
int main()
{
    int i, val, ret;
    int a[8]={-32, 12, 16, 24, 36, 45, 59, 98};
    for(i=0; i<8; i++)
        printf("%d\t", a[i]);
    printf("\n请输人所要查找的元素:");
    scanf("%d",&val);
    ret = binarySearch(a,8,val);
    if(-1 == ret)
        printf("查找失败 \n");
    else{
        printf ("查找成功a[%d]:%d\n", ret, a[ret]);
        
    }
        
    return 0;
}

运行结果:

-32 12 16 24 36 45 59 98

请输入所要查找的元素:12

查找成功

在上面的代码中,我们成功地通过二分査找算法实现了查找功能,其实现过程如下图所示。

二分査找算法的査找过程

        在如上图所示的查找过程中,先将序列中间位置的元素与所要査找的元素进行比较,发现要査找的元素位干该位置的左部分序列中。接下来将mid的左边一个元素作为 high,继续进行二分査找,这时mid所对应的中间元素刚好是所要査找的元素,査找结束,返回査找元素所对应的下标。在main函数中通过返回值来判断査找是否成功,如果査找成功.就打印输出“査找成功”的信息,否则输出“査找失畋”的信息。

8.结语

        在本篇博客中,我们深入探讨了数据结构中的常见排序和查找算法。排序算法不仅在数据处理和分析中扮演着重要角色,也为后续的数据操作打下了良好的基础。而查找算法则帮助我们高效地定位和访问数据,这对于提高程序性能来说至关重要。

        不同的排序和查找算法各有优缺点,适用于不同的场景。选择合适的算法不仅能提升程序的效率,还能优化资源的使用。了解这些算法背后的原理和应用场景,将为你在数据处理领域打下坚实的基础。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2050836.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

c++ opencv开发环境搭建

打开opencv官网&#xff0c;OpenCV - Open Computer Vision Library 然后点击之后&#xff0c;下载即可&#xff0c;下载完成之后&#xff0c;点击安装&#xff0c;等待安装完毕。 这是安装完毕之后的目录&#xff0c;已经包含了头文件与lib库、dll等&#xff0c;开发之前的环境…

RK3568平台(触摸篇)主板端集成厂家触摸屏

一.硬件连接 板卡配触摸框架构如下图&#xff1a; 二.数据流向 板卡配触摸框的数据流向&#xff0c;尽量做到高灵活性&#xff0c;并且简单清晰&#xff1a; 1&#xff09;后台进程从触摸框获取原始数据并计算&#xff0c;计算的点报给 android 内核 input 系统&#xff0c…

【AI/算法类】OPPO 2025届秋招笔试题(B卷)

目录 1. 第一题2. 第二题3. 第三题 ⏰ 时间&#xff1a;2024/08/10 &#x1f504; 输入输出&#xff1a;ACM格式 ⏳ 时长&#xff1a;2h 本试卷还有选择题部分&#xff0c;但这部分比较简单就不再展示。 1. 第一题 小O有一个正整数 x x x&#xff0c;他想知道&#xff0c;第…

【机器学习】(基础篇五) —— 逻辑回归

逻辑回归 逻辑回归&#xff08;Logistic Regression&#xff09;是一种广义线性模型&#xff0c;主要用于处理因变量为二分类或多分类&#xff08;通过独热编码或多输出逻辑回归&#xff09;的问题。尽管名字中带有“回归”二字&#xff0c;但实际上逻辑回归是一种分类算法&am…

SQLite数据库的增删改查(CRUD)

文章目录 SQLite数据库的增删改查&#xff08;CRUD&#xff09;添加数据更新数据删除数据查询数据使用SQL操作数据库添加数据的方法如下&#xff1a;更新数据的方法如下&#xff1a;删除数据的方法如下&#xff1a;查询数据的方法如下&#xff1a; SQLite数据库的增删改查&…

web技术1——jdk目录结构(重要),tomcat服务器(重要)

jdk文件夹结构(重要) bin目录&#xff1a; 里面都是.exe可执行文件。java&#xff0c;javac&#xff0c;javadoc&#xff0c;java编译工具&#xff0c;java监测工具等.exe文件都在这里。 include目录: 底层有用c写的东西&#xff0c;这里面包含很多c语言的文件&#xff0c…

Qt传入参数到mysql语句

试过两种方法都成功了 方法1&#xff1a;使用bool QSqlQuery::prepare和void QSqlQuery::bindValue传入参数,然后再使用bool QSqlQuery::exec() 执行Mysql语句 QSqlDatabase db //数据库 QSqlQuery result(db); // 基于已连接的数据库db建立 QSqlQuery 对象 QString strTime…

Linux du命令估算文件空间使用情况

du命令&#xff0c;估算文件空间使用情况&#xff0c;命令格式&#xff1a; du [option]... [file]... option&#xff1a; -a, --all显示所有文件的计数&#xff0c;而不仅仅是目录-d, --max-depthN打印文件夹深度小于等于N的总空间-h, --human-readable以人性化可读格式打…

Kotlin学习-01创建kotlin学习环境

安装idea https://www.jetbrains.com/zh-cn/ 创建项目 选择kotlin 修改Main.kt fun main() {print("Hello World!") }运行

类与对象(中(1))

开头 上一期内容&#xff0c;我们初步学习了类与对象中的基础知识&#xff0c;了解了类的定义&#xff0c;实例化以及this指针等相关内容&#xff0c;不知各位是否有一定的收获。今天&#xff0c;我们将更进一步&#xff0c;对类与对象中的默认成员函数部分进行一个初步的了解…

【排序篇】实现快速排序的三种方法

&#x1f308;个人主页&#xff1a;Yui_ &#x1f308;Linux专栏&#xff1a;Linux &#x1f308;C语言笔记专栏&#xff1a;C语言笔记 &#x1f308;数据结构专栏&#xff1a;数据结构 文章目录 1 交换排序1.1 冒泡排序1.2 快速排序1.2.1 hoare版本1.2.2 挖坑法1.2.3 前后指针…

C++求职LinuxWebServer面试篇(项目介绍)

⭐️我叫忆_恒心,一名喜欢书写博客的在读研究生👨‍🎓。 如果觉得本文能帮到您,麻烦点个赞👍呗! 近期会不断在专栏里进行更新讲解博客~~~ 有什么问题的小伙伴 欢迎留言提问欧,喜欢的小伙伴给个三连支持一下呗。👍⭐️❤️ Qt5.9专栏定期更新Qt的一些项目Demo 项目与…

【数学建模】趣味数模问题——棋子颜色问题

问题描述&#xff1a; 在任意拿出黑白两种颜色的棋子共 n 个&#xff0c;随机排成一个圆圈。然后根据以下规则放置棋子&#xff1a; 在两颗颜色相同的棋子中间放一颗黑色棋子在两颗颜色不同的棋子中间放一颗白色棋子 放完后撤掉原来所放的棋子&#xff0c;重复以上过程&…

仿某知识蝉在线学习副业项目知识付费系统小程序源码

一、仿知识蝉知识付费系统源码简介 知识付费系统&#xff0c;集合了图文、音频、视频、直播授课&#xff0c;专栏&#xff0c;品牌商城等主流功能和付费形式&#xff0c;并且包含多种多样的营销方案和互动模块&#xff0c;打造属于自己的知识付费系统。 安装步骤&#xff1a;…

聚星文社的工具使用0.2.9版本

聚星文社是一个在线写作社区&#xff0c;提供多种工具供用户使用。以下是聚星文社的工具使用说明&#xff1a; 聚星文社的工具https://docs.qq.com/doc/DRU1vcUZlanBKR2xy 写作工具&#xff1a;聚星文社提供了一个强大的在线写作工具&#xff0c;包括富文本编辑器、字数统计、拼…

计算机毕业设计选题推荐-民宿管理系统-酒店预定系统-Java/Python项目实战

✨作者主页&#xff1a;IT研究室✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…

windows下TortoiseSVN切换账号的方法

前言 在项目开始初期的时候大家会使用一个默认账号,后面会根据需要给每个人分配各自的个人账号,这个时候就需要重登陆新的svn账号,下面就是讲解下怎样在windows下修改登录TortoiseSVN的账号。 方法 1.首先在桌面右键&#xff0c;选择TortoiseSVN-settings 2.进入设置页面&a…

Android常见的界面布局

目录 ​前言 1.线性布局LinearLayout 2.相对布局RelativeLayout 3.表格布局TableLayout 4.网格布局GridLayout 实现一个计算器界面 改Button按钮颜色 5.帧布局FrameLayout 前言 在Android应用程序中&#xff0c;界面是由布局和控件组成的。控件是功能单元&#xff0c;负…

【C++】深入探索类和对象:初始化列表及其static成员与友元

C语法相关知识点可以通过点击以下链接进行学习一起加油&#xff01;命名空间缺省参数与函数重载C相关特性类和对象-上篇类和对象-中篇 本章将分享C中类和对象最后章节“深入探索类和对象&#xff1a;初始化列表及其static成员与友元”&#xff0c;希望通过这几篇关于类和对象文…