24软专 程序设计

一、实现快速排序,简要分析时间复杂度、空间复杂度。

#include <stdio.h>

int Partition(int array[], int low, int high)
{
    // 取第一个元素为枢轴元素
    int pivot = array[low]; // 由于传入的数组可能是子数组,即未必由零开始,因此low所指的元素是第一个元素
    while (low < high)
    {
        while (low < high && array[high] >= pivot)
        {
            high--; // high指针往前移寻找比pivot小的元素
        }
        // 如果找到比pivot小的元素
        array[low] = array[high]; // 将元素移动到low所指位置
        while (low < high && array[low] <= pivot)
        {
            low++; // 同理,寻找大于pivot的元素
        }
        array[high] = array[low]; // 如果跳出循环满足的条件是low=high,那么交换array[high]和array[low]也不会对排序造成影响
    }                             // low等于high跳出循环,找到最终位置,左边所有元素小于pivot,右边所有元素大于pivot,这一趟排序完成
    array[low] = pivot;           // 此时low指针所指位置为pivot最终所处位置
    return low;                   // 返回low
}

void QuickSort(int array[], int low, int high)
{ // 快速排序
    if (low < high)
    {
        int pivotpos = Partition(array, low, high); // 对表进行划分,此时pivotpos所指元素已到达最终位置
        // 对左右子表递归进行划分
        QuickSort(array, low, pivotpos - 1);
        QuickSort(array, pivotpos + 1, high);
    }
}

int main()
{
    int array[11] = {11, 22, 32, 34, 15, 19, 28, 29, 20, 16, 21};
    QuickSort(array, 0, 10);
    for (int i = 0; i < 11; i++)
    {
        printf("%d ", array[i]);
    }
    return 0;
}

运行结果如下:

时间复杂度分析:快速排序的时间复杂度受到划分次数的影响,每一趟排序的时间复杂度为O(n),而最坏情况下,即在序列基本有序或逆序的情况下,需要n-1次调用排序,即算法时间复杂度为O(n*n),而在最理想情况下,每次划分可以做到近乎二分的效果,那么时间复杂度可以达到O(nlogn)(2的对数打不出来)。

空间复杂度:由于快速排序是递归的,因此需要借助一个递归工作栈来保存每层递归调用的必要信息,其容量与递归调用的最大层数一致。最好的情况下为O(logn);最坏情况下,要进行n-1次递归调用,因此栈的深度为O(n)。平均情况下为O(logn)。

二、int len(char *s),实现该递归函数,计算字符中最后一个单词的长度,若不存在单词,返回0。(字符串由大小写字母、空格组成)

#include <stdio.h>
int len(char *s)
{
    int length = 0; // 记录长度
    // 如果当前字符是空字符,返回0

    while (*s++ != '\0')
    {
        if (*s == ' ') // 遇到空格跳出循环进入递归
        {
            return len(++s);
        }
        length++;
    }
    return length;
}
int main()
{
    char *s;
    s = "hello world";
    printf("%d", len(s));
    return 0;
}

运行结果:

三、职工信息:工号、姓名、年龄。定义结构体,从键盘读入n个职工信息,结点顺序与读入一致。

#include <stdio.h>
#include <stdlib.h>
typedef struct
{
    char no[10];
    char name[10];
    int age;
} Staff;
typedef struct LNode
{
    Staff staffInfo;
    LNode *next;
} LNode, *LinkList;

void InitList(LinkList &L)
{
    L = (LNode*)malloc(sizeof(LNode));
    L->next = NULL;
}
void InsertList(LinkList &L,Staff sta){
    LNode *p=L;
    while(p->next!=NULL){
        p=p->next;
    }
    LNode *s=(LNode*)malloc(sizeof(LNode));
    s->staffInfo=sta;
    s->next=NULL;
    p->next=s;
}
int main()
{
    Staff sta;
    LNode *L;
    InitList(L);
    while (getchar() != '#')
    {
        scanf("%c %c %d",sta.no,sta.name,&sta.age);
        InsertList(L,sta);
    }
}

四、续写,将链表中工号重复的结点删除,并写入"worker.txt”中

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct
{
    char no[10];
    char name[10];
    int age;
} Staff;
typedef struct LNode
{
    Staff staffInfo;
    LNode *next;
} LNode, *LinkList;

void InitList(LinkList &L)
{
    L = (LNode *)malloc(sizeof(LNode));
    L->next = NULL;
}
void InsertList(LinkList &L, Staff sta)
{
    LNode *p = L;
    while (p->next != NULL)
    {
        p = p->next;
    }
    LNode *s = (LNode *)malloc(sizeof(LNode));
    s->staffInfo = sta;
    s->next = NULL;
    p->next = s;
}
int listLength(LinkList L)
{
    int length = 0;
    LNode *p = L;
    while (p->next != NULL)
    {
        length++;
        p = p->next;
    }
    return length;
}
bool isExist(char no[][10], char *staffno, int i)
{
    for (int j = 0; j < i; j++)
    {
        if (strcmp(no[j], staffno) == 0)
        {
            return true;
        }
    }
    return false;
}
void writeToFile(LinkList L)
{
    FILE *opf = fopen("worker.txt", "w");
    int length = listLength(L);
    char no[length][10];
    int i = 0;
    LNode *p = L;
    while (p->next != NULL)
    {
        p = p->next;
        if (!isExist(no, p->staffInfo.no, i))
        {
            fprintf(opf, "%s %s %d\n", p->staffInfo.no, p->staffInfo.name, p->staffInfo.age);
            strcpy(no[i], p->staffInfo.no);
            i++;
        }
    }
    fclose(opf);
}
int main()
{
    Staff sta;
    LNode *L;
    InitList(L);
    do
    {
        scanf("%s %s %d", sta.no, sta.name, &sta.age);
        InsertList(L, sta);
    } while (getchar() != '#'); // 后置循环检测,以免第一个字符丢失
    writeToFile(L);
    return 0;
}

运行结果:

文件内容:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值