数据结构——链表课后习题解答

学习完链表,做了一遍题,码完代码,能跑的都跑了一遍,检验了一下。答案若有错误,欢迎指出,感谢!

以下是题目和答案(以下题目若没有指出,全是用单向链表)

目录

1. 逆序一个链表

2.如何判断一个链表是否有环

3. 求链表的中间节点,要求只用一重循环。

4. 约瑟夫环的问题 

5.class List 

6.class List T 


1. 逆序一个链表

这个问题在我 单向链表 博客中已经写出了,这里我就不贴答案了,若想看答案,到我单向链表那里的看reverseList函数即可。

扫描二维码关注公众号,回复: 2470327 查看本文章

2.如何判断一个链表是否有环

这里主要是一个指针移动是一个节点的单位移动,另一个指针是两个节点为单位移动,如果有环,则肯定能相遇

void checkList(Node*head)
{
    Node*p,*q;
    p=p->next->next;
    q=q->next;
    while(q)
    {
        if(q==p)
        {
            printf("this is ring");
            exit(1);
        }
        p=p->next->next;
        q=q->next;
    }
    printf("this is not ring");
}

3. 求链表的中间节点,要求只用一重循环。

跟上面同理,设一个指针移动是一个节点的单位移动,另一个指针是两个节点为单位移动,当两个节点为单位的指针到达终点时,则另一个节点到达中点

我主要贴一下寻中点的函数,创建、插入函数就不贴了

list.h

#include<stdio.h>
#include<stdlib.h>
struct Node
{
        int data;
        struct Node * next;
};
Node * creatList();
void insertList(Node*head,int data);
Node*searchMiddleList(Node*head);

list.cpp

Node*searchMiddleList(Node*head)
{
    head=head->next;
    Node * cur=head;
    while(cur)
    {
        cur=cur->next->next;
        head=head->next;
    }
    return head;
}

main函数

include <iostream>
#include"list.h"
#include<ctime>
using namespace std;
int main()
{
    Node * head=creatList();
    srand(time(NULL));
    for(int i=0;i<10;i++)
    {
        insertList(head,rand()%10);
    }
    traverseList(head);
    Node*cur=searchMiddleList(head);
    cout<<endl;
    cout<<"the middle data is "<<cur->data<<", the Node is "<<cur<<endl;
    return 0;
}

4. 约瑟夫环的问题 

n个人围成圈,依次编号为1,2,..,n,现在从1号开始依次报数,当报到m时,报m的人退出,下一个人重新从1报起,循环下去,问最后剩下那个人的编号是多少? 

这个问题需要用 双向链表 解决,代码如下:

dlist.h

#include<stdio.h>
#include<stdlib.h>
struct DNode
{
    int data;
    struct DNode*next;
    struct DNode*pre;
};

DNode*creatDList();

void traverseDList(DNode*head);

void insertDList(DNode*head,int data);

void deleteDList(DNode*pfind);

DNode* JosephProblem(DNode*head,int num);

//这里问题问的是编号多少,我这里把最后的节点输出,这里用遍历也能得到最后的编号,因为编号是顺序

PS: 这里我用了C++的文件格式,但是用C语言文件也可以,只要把main函数的输出格式改成C语言格式,就可以了

list.cpp

#include"dlist.h"
DNode*creatDList()
{
    DNode*head=(DNode*)malloc(sizeof(DNode));
    head->next=head;
    head->pre=head;
    return head;
}

void traverseDList(DNode*head)
{
    DNode* cur=head;
    cur=cur->next;

    while(cur != head)
    {
        printf("%d\t",cur->data);
        cur=cur->next;
    }
}

void insertDList(DNode*head,int data)
{
    DNode*cur=(DNode*)malloc(sizeof(DNode));
    cur->data=data;

    cur->next=head->next;
    head->next=cur;
    cur->pre=head;
    cur->next->pre=cur;
}

void deleteDList(DNode*pfind)
{
    pfind->pre->next=pfind->next;
    pfind->next->pre=pfind->pre;
    free(pfind);
}

DNode* JosephProblem(DNode*head,int num)
{
    int count=1;
    DNode*cur=head;
    cur=cur->next;
    while(1)
    {
        if(cur==head)
        {
            cur=cur->next;
            continue;
        }
        if(count==num)
        {
            DNode*th=cur;
            if(cur->next != head || cur->pre!=head)  //关键一步,判断到这个数的节点是不是最后一个节点,不是的话删除
            {
                cur=cur->next;
                deleteDList(th);
                count=1;
            }
            else   //若是最后一个节点,则输出
                 return cur;
        }
        else
        {
            count++;
            cur=cur->next;
        }
    }
}

main函数

#include <iostream>
#include"dlist.h"
using namespace std;
int main()
{
    DNode *head=creatDList();
#if 1   //这一步,我主要是想自己键盘输入总编号
    int num;
    scanf("%d",&num);
    for(int i=num;i>0 ;i--)
    {
        insertDList(head,i);
        if(i==1)
            break;
    }
#endif

#if 0
    for(int i=10;i>0;i--)
        insertDList(head,i);
#endif

    traverseDList(head);
    cout<<endl;
    int num2=0;
    cout<<"请输入步长:";
    scanf("%d",&num2);
    DNode* cur= JosephProblem(head,num2);
    traverseDList(head);
    return 0;
}

5.class List 

这里是把List做成一个类,代码如下:

list.h

#include<iostream>
using namespace std;
struct Node
{
        int data;
        struct Node* next;
};

class List
{
    public:
        List();          //创建空链表
        ~List();        //销毁链表

        void insertList(int data);
        void traverseList();
    private:
        Node*head;
};

list.cpp

#include "list.h"//函数内容跟之前本质是一样的,这里只写了一部分
List::List()
{
    head=new Node;
    head->next=NULL;
}

List::~List()  //全部销毁
{
    Node*t=head;
    while(head)
    {
        head=head->next;
        delete t;
        t=head;
    }
}

void List::insertList(int data)
{
    Node*cur=new Node;
    cur->data=data;
    cur->next=head->next;
    head->next=cur;
}
void List::traverseList()
{
    Node* ph =head->next;
    while(ph)
    {
        cout<<ph->data<<endl;
        ph=ph->next;
    }
}

main函数

#include <iostream>
#include"list.h"
using namespace std;

int main()
{
    List list;
    for(int i=0;i<10;i++)
        list.insertList(i);
    list.traverseList();
    return 0;
}

6.class List T 

利用泛型编程实现链表,代码如下:

mylist.h  

注意:模板定义很特殊。由template<…>处理的任何东西都意味着编译器在当时不为它分配存储空间,它一直处于等待状态直到被一个模板实例告知。在编译器和连接器的某一处,有一机制能去掉指定模板的多重定义。所以为了容易使用,几乎总是在头文件中放置全部的模板声明和定义,若放在cpp里编译不通过

#include<iostream>
using namespace std;
template<typename T>
class myList
{
    public:
        myList(); //创建链表
        ~myList();//销毁
        void traverseList();
        void insertList(T data);
    protected:
        struct Node
        {
            T data;
            Node*next;
        };
    private:
        Node*head;
};

template<typename T>  //每个函数前都要写,注意格式,其他跟上面的 class 一样
myList<T>::myList()
{
    head=new Node;
    head->next=NULL;
}

template<typename T>
myList<T>::~myList()
{
    Node*cur=head;
    while(head)
    {
        head=head->next;
        delete cur;
        cur=head;
    }
}
template<typename T>
void myList<T>::traverseList()
{
    Node*cur=head->next;
    while(cur)
    {
        cout<<cur->data<<endl;
        cur=cur->next;
    }
}
template<typename T>
void myList<T>::insertList(T data)
{
    Node*cur=new Node;
    cur->data=data;
    cur->next=head->next;
    head->next=cur;
}

main函数

#include <iostream>
#include "mylist.h"
using namespace std;
int main()
{
#if 0
    myList<int>list;
    for(int i=0;i<10;i++)
        list.insertList(i);
    list.traverseList();
#endif
    myList<char>list;
    for(char i='a';i<'f';i++)
        list.insertList(i);
    list.traverseList();
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载

猜你喜欢

转载自blog.csdn.net/weixin_42513339/article/details/81213803
今日推荐