• 按升序顺序插入构建线性表


    任务描述

    本关要求按照数据输入,通过按升序插入节点的方法,构建一个升序线性表。即如果输入的3个结点数据分别为231,则构建的线性表包含3个结点,且从前往后的结点数据分别为123

    编程要求

    本关的编程任务是补全step3/insertSort.h文件中的insertSort函数,以实现按升序排序方式构建线性表的要求。具体要求如下:

    insertSort函数的实现可以分为两个步骤:

    • 一是找到插入点;
    • 二是插入结点。

    (1)如何找到插入点 插入点的定位可以使用两个指针(pq),定位步骤如下图所示:

    上图中链表有4个结点,则共有5个可能的插入点。用两个指针首先定位第一个插入点(step1pNULLq指向第一个结点),如果插入结点的data小于q指向结点的data,则就是该插入点(两个指针指向的结点之间),否则两个指针一起往后移动(step2);定位第二个插入点,判断条件依然是插入结点的data是否小于q指向的结点的data,是则就是该插入点,否则两个指针往后平移(step3);定位第三个插入点……直到最后当q指针为NULL时,说明插入结点的data比链表中所有数据都大,则插入点应该是链尾(第5个插入点)。插入点的定位操作可以很容易地用循环实现。

    定位好插入点后,当pNULL时,插入点是链表头部;当qNULL时,插入点是链表尾部;否则,插入点为pq指向的两个结点之间。

    (2)如何插入结点 上述定位好插入点后,接下来是插入结点。对于头部插入和尾部插入的内容前两关已做过介绍,本关只介绍中间插入的情况,即将t指向的结点插入到pq指向的两个结点之间。这种情况只需要让p指向结点的指针域指向t指向的结点,t指向结点的指针域指向q指向的结点即可。具体参见下面代码:

    1. p->next = t;
    2. t->next = q;

    评测说明

    本关中包含三个文件分别是: step3/insertSort.h :此文件为学员文件,包含向链表升序插入元素函数实现。 step3/linkList.h:此文件包含链表常见操作的说明与实现,引用了insertSort.h step3/test.cpp:此文件为评测文件(含main函数),引用“linkList.h”。 (上述三个文件可通过点击在代码取的右上角文件夹中的step3文件夹中查看) (注意:本关所实现链式线性表为带头结点的单链表)

    输入输出说明

    输入n(1<=n<=100),再输入n个整数,按所输入整数的升序顺序输出这n个整数,如下所示:(注意:链表的输出函数已经实现,详情请阅读step3文件夹中的文件。) 测试输入: 5 6 5 7 4 8 预期输出: List: 4 5 6 7 8

    测试输入: 7 9 8 7 2 3 4 0 预期输出: List: 0 2 3 4 7 8 9

    insertSort.h

    // 函数insertSort:链表升序插入
    // 参数:h-链表头指针,t-指向要插入的结点
    // 返回值:插入结点后链表的首结点地址
    node* insertSort(struct node* h, struct node* t)
    {
        // 请在此添加代码,补全函数insertSort
        /********** Begin *********/
        struct node* current;
        if(h == NULL || h->data>=t->data){
            t->next = h; 
            h= t; 
        }
        else{
            current=h;
            while (current->next!=NULL && 
                   current->next->data < t->data) 
            { 
                current = current->next; 
            } 
            t->next = current->next; 
            current->next = t; 
        }
        return h;
        /********** End **********/
    }

    linkList.h

    #include <iostream>
    using namespace std;
    
    // 定义结点结构
    struct node
    {
        int data;  // 数据域
        node* next;  // 指针域,指向下一个结点
    };
    
    // 函数insertSort:链表升序插入
    // 参数:h-链表头指针,t-指向要插入的结点
    // 返回值:插入结点后链表的首结点地址
    node* insertSort(node* h, node* t);
    
    // 函数printList:输出链表,每个数据之间用一个空格隔开
    // 参数:h-链表头指针
    void printList(node* h);
    
    
    
    // 函数delList:删除链表,释放空间
    // 参数:h-链表头指针
    void delList(node* h);
    
    
    #include"insertSort.h" //包含node* insertHead(node* h, node* t)函数的实现
    
    void delList(node* h)
    {
        node* p = h; //指针p指向头结点,第一个要删除的结点
        while (p) //这个结点是存在的
        {
            h = h->next; //头指针h指向下一个结点(下一个结点的地址存在当前结点的指针域中,即h->next中
            delete p; //删除p指向的结点
            p = h; //p指向当前的头结点,即下一个要删除的结点
        }
    }
    //函数printList:输出链表,每个数据之间用一个空格隔开
    //参数:h-链表头指针
    void printList(node* h)
    {
        cout << "List:";
        if (h->next != NULL) h = h->next;
        while (h)
        {// h为真,即h指向的结点存在,则输出该结点的数据
            cout << " " << h->data;  // 输出结点数据
            h = h->next;  // 将该结点的指针域赋值给h,h就指向了下一个结点
        }
        cout << endl; // 输出换行符
    }

    test.cpp

    #include "linkList.h"
    
    int main()
    {
        int n, i;
        node* t;
        node* head = new node;// 带头结点单链表,头结点指针head
        head->next = NULL; // 头结点head->next==NULL,链表为空
        //输入结点数
        cin >> n;
        for (i = 0; i < n; i++)
        {
            //为新节点动态分配空间
            t = new node;
            cin >> t->data; //输入结点数据
            t->next = NULL;  //结点指针域值为空
            //调用函数插入结点到链表头部
            head = insertSort(head, t);
        }
        //输出链表
        printList(head);
        //删除结点,释放空间
        delList(head);
    
        return 0;
    }
  • 相关阅读:
    Java微信二次开发(八)
    Java微信二次开发(七)
    Java微信二次开发(六)
    Java微信二次开发(五)
    Java微信二次开发(四)
    Java微信二次开发(三)
    IIS中X509Certificate遇见的问题
    SQL Server 数据库定时自动备份
    ASP.NET 5 (vNext) 理解和概述
    ASP.NET 5 (vNext) Linux部署
  • 原文地址:https://www.cnblogs.com/xxxsans/p/13892498.html
Copyright © 2020-2023  润新知