2021秋季《数据结构》_第一章书面作业

这篇博客涵盖了几个关于链表的操作,包括如何逆转单链表、在单链表中插入新节点以及如何合并两个有序的环形链表。逆转链表的函数通过迭代法实现,插入函数允许在找到特定值节点前插入新节点,而合并环形链表的函数则创建了一个新的有序环形链表。此外,还讨论了广义表的深度计算问题,提供了相应的C函数实现。
摘要由CSDN通过智能技术生成

代码

  1. 编写一个将给定的线性单链表逆转的函数,只允许改变结点的指针值,不允许移动结点值,返回逆转后的链表的头指针。

    Node* reverse_Linklist(Node* head)
    // 带头结点
    {
        // 空表返回头结点
        if(!head->next) return head;
        else
        {
            Node* p = head->next;
            Node* tmp = NULL;       // 待修改指针的结点
            Node* front = NULL;     // 存放tmp的上一个结点
                                    // 由于尾结点指向NULL,初始化为NULL
            while (p->next)
            {
                tmp = p;
                p = p->next;
                tmp->next = front;  // 指向上一个结点
                front = tmp;        // 更新front
            }
            p->next = front;        // 修改尾结点的指针
            head->next = p;         // 头结点指向原来的尾结点
            return head;
        }
    }
    
  2. 对于给定的单链表,编写一个把值为 a 的结点插在值为 b 的结点的前面的函数。若值为b的结点不在线性链表中,则把 a 插在链表的最后。若有多个值为 b 的结点,则插在第一个出现的 b 结点之前。

    Node* insertLinklist_t2(Node* head, int a, int b)
    // 把值为 a 的结点插在值为 b 的结点前面
    {
        if(!head->next) return head;
        else
        {
            Node* tmp = new Node;
            tmp->data = a;
            Node* p = head;
            while (p->next)  // 找值为b的结点
            {
                if(p->next->data==b)
                    break;
                p = p->next;
            }
            tmp->next = p->next;
            p->next = tmp;
            return head;
        }
    }
    
  3. (已改正)假设 A 和 B 是两个按结点值从小到大排列的有序环形链表(带表头结点,表头结点中不存放有效信息)。试编写一个将这两个有序的环形链表归并为一个按节点值从小到大排列的有序环形链表的 C 函数。

Node* MergeLinkList(Node* head1, Node* head2)
{
    Node* p1 = head1->next;
    Node* p2 = head2->next;
    Node* head = p1->data<p2->data? head1:head2;            // 挑选首结点较小的头结点作为头结点
    Node* front = head;                                     // 记录当前结点,作为遍历时结点的上一个结点
    while (p1!=head1 && p2!=head2)
    {
        if(p1->data<p2->data)
        {
            front->next = p1;                             
            front = p1;
            p1 = p1->next;
        }
        else
        {
            front->next = p2;
            front = p2;
            p2 = p2->next;
        }
    }

    while(p1!=head1)
    {
        front->next = p1;
        front = p1;
        p1 = p1->next;
    }  
    
    while (p2!=head2)
    {
        front->next = p2;
        front = p2;
        p2 = p2->next;
    }
    
    front->next = head;
    
    return head;
}
  1. 求广义表的深度。我们规定空的广义表的深度为 0,而一般地有
    d e p t h ( s ) = { 1 , 若 s 是 一 个 原 子 1 + m a x { d e p t h ( a 0 ) , ⋯   , d e p t h ( a n − 1 ) , 若 s 是 广 义 表 ( a 0 , a 1 , ⋯   , a n − 1 ) } depth(s)= \begin{cases} 1, & 若s是一个原子 \\ 1+max\{depth(a_0),\cdots,depth(a_{n-1}), & 若s是广义表(a_0, a_1, \cdots, a_{n-1})\} \end{cases} depth(s)={1,1+max{depth(a0),,depth(an1),ss广(a0,a1,,an1)}
    编写一个求解广义表 s s s的深度的C函数。

    • 思考

      1. 如果是一个递归表,你的函数会输出什么结果?

        广义表 C = ( a , C ) C=(a, C) C=(a,C) a a a为原子, C C C为一个广义表

      2. 在写递归程序时,需要特别注意哪些情况?

    int glistDepth(GNode* C)
    {
        if (!C)  // 如果C为空表,返回长度0
        {
            return 0;
        }
        if (C->tag == 0)
        // 如果C为原子,返回长度1
        {
            return 1;
        }
        int max = 0;
        for (GNode* p = C; p; p = p->ptr.tp)
        // 遍历每一个子表,寻找最大深度
        {
            int depth = glistDepth(p->ptr.hp);
            if (max < depth) max = depth;
        }
        return max+1;
    }
    
    注意判断空表情况
    注意判断递归终止条件:子表为原子的情况
    

附录

测试代码:

  1. #include<bits/stdc++.h>
    using namespace std;
    
    typedef struct  node
    {
        int data;
        struct node* next;
    }Node;
    
    Node* initLinklist(Node* head)
    {
        head = new Node;
        head->data = 0;
        head->next = NULL;
        return head;
    }
    
    Node* insertLinklist(Node* head, int n)
    // 尾插
    {
        Node* L = head;
        for(int i = 0; i < n; i++)
        {
            Node* p = new Node;
            cin>>p->data;
            p->next = NULL;
            L->next = p;
            L = p;
        }
        return head;
    }
    
    void printLinklist(Node* head)
    {
        Node* p = head->next;
        while (p)
        {
            cout<<p->data<<' ';
            p = p->next;
        }
        cout<<endl;
        
    }
    
    Node* reverse_Linklist(Node* head)
    // 带头结点
    {
        // 空表返回头结点
        if(!head->next) return head;
        else
        {
            Node* p = head->next;
            Node* tmp = NULL;       // 待修改指针的结点
            Node* front = NULL;     // 存放tmp的上一个结点
                                    // 由于尾结点指向NULL,初始化为NULL
            while (p->next)
            {
                tmp = p;
                p = p->next;
                tmp->next = front;  // 指向上一个结点
                front = tmp;        // 更新front
            }
            p->next = front;        // 修改尾结点的指针
            head->next = p;         // 头结点指向原来的尾结点
            return head;
        }
    }
    
    int main()
    {
        Node* head;
        head = initLinklist(head);
        cout<<"Please enter the number of elements"<<endl;
        int n; cin>>n;
        cout<<"Please enter the values(>0) of elements"<<endl;
        insertLinklist(head, n);
        cout<<"The original order is:"<<endl;
        printLinklist(head);
        reverse_Linklist(head);
        cout<<"The reversed order is:"<<endl;
        printLinklist(head);
        system("pause");
        return 0;
    }
    
  2. #include<bits/stdc++.h>
    using namespace std;
    
    typedef struct  node
    {
        int data;
        struct node* next;
    }Node;
    
    Node* initLinklist(Node* head)
    {
        head = new Node;
        head->data = 0;
        head->next = NULL;
        return head;
    }
    
    Node* insertLinklist(Node* head, int n)
    {
        Node* L = head;
        for(int i = 0; i < n; i++)
        {
            Node* p = new Node;
            cin>>p->data;
            p->next = NULL;
            L->next = p;
            L = p;
        }
        return head;
    }
    
    Node* insertLinklist_t2(Node* head, int a, int b)
    // 把值为 a 的结点插在值为 b 的结点前面
    {
        if(!head->next) return head;
        else
        {
            Node* tmp = new Node;
            tmp->data = a;
            Node* p = head;
            while (p->next)  // 找值为b的结点
            {
                if(p->next->data==b)
                    break;
                p = p->next;
            }
            tmp->next = p->next;
            p->next = tmp;
            return head;
        }
    }
    
    void printLinklist(Node* head)
    {
        Node* p = head->next;
        while (p)
        {
            cout<<p->data<<' ';
            p = p->next;
        }
        cout<<endl;
        
    }
    
    int main()
    {
        Node* head;
        head = initLinklist(head);
        cout<<"Please enter the number of elements"<<endl;
        int n; cin>>n;
        cout<<"Please enter the values(>0) of elements"<<endl;
        insertLinklist(head, n);
        cout<<"The original order is:"<<endl;
        printLinklist(head);
        insertLinklist_t2(head, 1, 2);
        cout<<"The inserted order is:"<<endl;
        printLinklist(head);
        system("pause");
        return 0;
    }
    
  3. #include<bits/stdc++.h>
    using namespace std;
    
    typedef struct  node
    {
        int data;
        struct node* next;
    }Node;
    
    Node* initCircularList(Node* head)
    {
        head = new Node;
        head->data = 0;
        head->next = head;
        return head;
    }
    
    Node* insertCircularList(Node* head, int n)
    // 尾插
    {
        Node* L = head;
        for(int i = 0; i < n; i++)
        {
            Node* p = new Node;
            cin>>p->data;
            p->next = L->next;
            L->next = p;
            L = p;
        }
        return head;
    }
    
    Node* MergeLinkList(Node* head1, Node* head2)
    {
        Node* p1 = head1->next;
        Node* p2 = head2->next;
        Node* head = p1->data<p2->data? head1:head2;            // 挑选首结点较小的头结点作为头结点
        Node* front = head;                                     // 记录当前结点,作为遍历时结点的上一个结点
        while (p1!=head1 && p2!=head2)
        {
            if(p1->data<p2->data)
            {
                front->next = p1;                             
                front = p1;
                p1 = p1->next;
            }
            else
            {
                front->next = p2;
                front = p2;
                p2 = p2->next;
            }
        }
    
        while(p1!=head1)
        {
            front->next = p1;
            front = p1;
            p1 = p1->next;
        }  
        
        while (p2!=head2)
        {
            front->next = p2;
            front = p2;
            p2 = p2->next;
        }
        
        front->next = head;
        
        return head;
    }
    
    void printCircularList(Node* head)
    {
        Node* p = head->next;
        while (p!=head)
        {
            cout<<p->data<<' ';
            p = p->next;
        }
        cout<<endl;
    }
    
    
    int main()
    {
        Node* head1, *head2;
        head1 = initCircularList(head1);
        head2 = initCircularList(head2);
        cout<<"Please enter the number of elements in list1:"<<endl;
        int n1; cin>>n1;
        cout<<"Please enter the values of elements in list1:"<<endl;
        insertCircularList(head1, n1);
        cout<<"The original order of list1 is:"<<endl;
        printCircularList(head1);
        cout<<"Please enter the number of elements in list2:"<<endl;
        int n2; cin>>n2;
        cout<<"Please enter the values of elements in list2:"<<endl;
        insertCircularList(head2, n2);
        cout<<"The original order of list2 is:"<<endl;
        printCircularList(head2);
        cout<<"The merged list is:"<<endl;
        Node* head = MergeLinkList(head1, head2);
        printCircularList(head);
        
    
        system("pause");
        return 0;
    }
    
    // 3
    // 1 4 6
    // 4
    // 2 3 5 7
    
    
  4. #include<bits/stdc++.h>
    using namespace std;
    
    typedef struct node
    {
    	int tag;
    	union
    	{
    		char atom;
    		struct
    		{
    			struct node* hp, * tp;
    		}ptr;
    	};
    }GNode, *Glist;
    
    Glist creatGlist(Glist C) {
        //广义表C
        C = (Glist)malloc(sizeof(Glist));
        C->tag = 1;
        //表头原子‘a’
        C->ptr.hp = (Glist)malloc(sizeof(Glist));
        C->ptr.hp->tag = 0;
        C->ptr.hp->atom = 'a';
        //表尾子表(b,c,d),是一个整体
        C->ptr.tp = (Glist)malloc(sizeof(Glist));
        C->ptr.tp->tag = 1;
        C->ptr.tp->ptr.hp = (Glist)malloc(sizeof(Glist));
        C->ptr.tp->ptr.tp = NULL;
        //开始存放下一个数据元素(b,c,d),表头为‘b’,表尾为(c,d)
        C->ptr.tp->ptr.hp->tag = 1;
        C->ptr.tp->ptr.hp->ptr.hp = (Glist)malloc(sizeof(Glist));
        C->ptr.tp->ptr.hp->ptr.hp->tag = 0;
        C->ptr.tp->ptr.hp->ptr.hp->atom = 'b';
        C->ptr.tp->ptr.hp->ptr.tp = (Glist)malloc(sizeof(Glist));
        //存放子表(c,d),表头为c,表尾为d
        C->ptr.tp->ptr.hp->ptr.tp->tag = 1;
        C->ptr.tp->ptr.hp->ptr.tp->ptr.hp = (Glist)malloc(sizeof(Glist));
        C->ptr.tp->ptr.hp->ptr.tp->ptr.hp->tag = 0;
        C->ptr.tp->ptr.hp->ptr.tp->ptr.hp->atom = 'c';
        C->ptr.tp->ptr.hp->ptr.tp->ptr.tp = (Glist)malloc(sizeof(Glist));
        //存放表尾d
        C->ptr.tp->ptr.hp->ptr.tp->ptr.tp->tag = 1;
        C->ptr.tp->ptr.hp->ptr.tp->ptr.tp->ptr.hp = (Glist)malloc(sizeof(Glist));
        C->ptr.tp->ptr.hp->ptr.tp->ptr.tp->ptr.hp->tag = 0;
        C->ptr.tp->ptr.hp->ptr.tp->ptr.tp->ptr.hp->atom = 'd';
        C->ptr.tp->ptr.hp->ptr.tp->ptr.tp->ptr.tp = NULL;
        return C;
    }
    
    int glistDepth(GNode* C)
    {
        if (!C)  // 如果C为空表,返回长度0
        {
            return 0;
        }
        if (C->tag == 0)
        // 如果C为原子,返回长度1
        {
            return 1;
        }
        int max = 0;
        for (GNode* p = C; p; p = p->ptr.tp)
        // 遍历每一个子表,寻找最大深度
        {
            int depth = glistDepth(p->ptr.hp);
            if (max < depth) max = depth;
        }
        return max+1;
    
    }
    
    int main()
    {
        GNode* C = NULL;
        C = creatGlist(C);
        cout << glistDepth(C) << endl;
    	return 0;
    }
    
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值