C++练习题2

实验内容1:建立头文件Seqlist.h,将源文件main.cpp中上次作业内容注释,编写本次主函数内,通过调用头文件,完成对线性表(x,x,x,x,x,x)的操作:

1,建立空表a

2,建立顺序表b, 并显示结果

3,在位置4处插入6, 并显示结果

4,删除位置3处的值, 并显示结果

5,查找位置5处的值为:

6,查找数值4在线性表中的位置为:

7,顺序表的长度是:

8,顺序表是否为空:

实验内容2:

编写单链表程序 linklist.h(包括建立空表,构造函数(头插法或尾插法二选一)、遍历操作、求长度、按位查找、按值查找、插入、删除、析构函数)。

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

源文件main.cpp

#include <iostream>
#include "SeqList.h"
#include "LinkList.h"
int main()
{
    cout<<"-----顺序表操作的实现-----"<<endl;
    double b[]= {1,4,6,2,9,11,1};
    SeqList<double> S;//创建对象
    S.SeqList0(b);
    cout<<"原始顺序表为:";
    S.PrintList();
    cout<<""<<endl;//换行

    S.Insert(5,7);//插入
    cout<<"在第5个位置插入7为:";
    S.PrintList();
    cout<<""<<endl;

    S.Delete(3);//删除
    cout<<"删除第3个位置元素为:";
    S.PrintList();
    cout<<""<<endl;

    cout<<"按位查找,查找第6个元素值为:"<<S.get(6)<<endl;
    cout<<"最大值为:"<<S.MAX()<<endl;
    S.Sort();//排序
    cout<<"从小到大排序为:";
    S.PrintList();

    S.Sort_reverse();
    cout<<"从大到小排序为:";
    S.PrintList();
    cout<<""<<endl;


    cout<<"-----链表操作的实现-----"<<endl;
    LinkList<double> L;
    L.LinkList0(b);
    cout<<"链表的长度为"<<L.Length()<<endl;
    cout<<"原始链表内具体内容:"<<endl;
    L.PrintList();
    cout<<"获取第3个结点的元素值:";
    cout<<L.Get(3)<<endl;
    cout<<"查找元素值为6的结点序号:";
    cout<<L.Find_id(6)<<endl;
    L.Insert(3,22);
    cout<<"将22插入第3个结点:"<<endl;
    L.PrintList();
    L.Delete(5);
    cout<<"删除第5个结点:"<<endl;
    L.PrintList();
    return 0;
}

头文件LinkList.h

#ifndef LINKLIST_H_INCLUDED
#define LINKLIST_H_INCLUDED
//链表头文件
template <typename T>
struct Node //定义节点
{
    T data;//数据域
    Node<T> *t;//指针域
};

template <typename T>
struct LinkList
{
    void LinkList0(T a[]);//建立有元素的单链表
    void PrintList();//打印链表数据域
    T Get(int i);//按位查找,查找第i个结点的元素值
    int Find_id(T x);//按值查找,查找值为x的元素序号
    int Length();//输出链表的长度
    void Insert(int i,T x);//插入操作,第i个位置插入值为x的结点
    void Delete(int i);//删除操作,删除第i个结点
    private:
    int length;
    Node<T> *first;//定义first数据类型指针,因为它是整个类的全局变量,会被多个方法使用,所以定义在这里
};

template <typename T>
void LinkList<T>::LinkList0(T a[])
{
    int n;
    for(int i=0; i<9999; i+=1)
    {
        if(a[i]<1e-300) break;//判断输入的值长度
        else n+=1;
    }
    length=n;
    first=new Node<T>;//创建头节点的指针,first有数据域与指针域,其自身代表数据域的地址
    first->t=nullptr;//将头节点中指针域定义为空
    for(int i=0;i<n;i+=1)
    {
        Node<T> *s=nullptr;//定义s的数据类型,为指针,并且赋予初值为空
        s=new Node<T>;//创建一个节点的指针(地址)
        s->data=a[i];//节点的数据域
        s->t=first->t;//节点的指针域(代表下一个节点的地址)
        first->t=s;//代表这一个节点i的地址,在下一个循环的时候,这个节点的地址会存到下一个节点的指针域,所以它是逆序创建
        //cout<<(*s).data<<" "<<s->data<<" "<<s->t<<"\t";
    }
}

template <typename T>
void LinkList<T>::PrintList()
{
    Node<T> *p;//代表p是结点(地址)
    p=first->t;//first代表头节点,first->t代表取头节点中指针域的内容,即下一个(第一个结点)的地址,即第一个结点地址给p
    //所以可以理解为这里p代表第一个结点
    //cout<<first->t<<" "<<p->t<<endl;
    while(p!=nullptr)
    {
        cout<<p->data<<" "<<(*p).t<<"\t";//输出这个结点的信息,包括数据域与指针域
        p=p->t;//将结点换成下一个结点
    }
    cout<<""<<endl;
    cout<<"打印结束"<<endl;
}

template <typename T>
T LinkList<T>::Get(int i)
{
    if(i>length) cout<<"get():超出结点长度"<<endl;
    int count=1;//计数器。方便定位当前是第几个结点
    Node<T> *p;
    p=first->t;//这里p代表第一个结点
    while(count!=i)//如果等于i就退出,这时p停到了第i个结点
    {
        p=p->t;//第动到下一个结点,如第一次循环,这里移动到了第二个结点,所以下面count加1,代表现在是第2个结点
        count+=1;
    }
    return p->data;//放回第i个结点的元素值
}

template <typename T>
int LinkList<T>::Find_id(T x)
{
    int count=1;//计数器,记录当前是第几个结点
    Node<T> *p=first->t;//初始化p,让p代表第一个结点
    while(p->data!=x&&p!=nullptr)//查看当前结点的元素是否等于要查找的元素,如果结点p为空,则说明最后一个结点查找完了也没有查找到
    {
        p=p->t;//含义与get()函数内注释一致
        //当p为最后一个结点的时候,p->代表这个结点内元素值,p->t代表下一个结点的地址,为空,while先执行,所以最后一个结点先被查找了一遍
        count+=1;
    }
    if(p==nullptr) cout<<"Find_id():未查找到元素"<<endl;
    return count;
}

template <typename T>
int LinkList<T>::Length()
{
    return length;
}

template <typename T>
void LinkList<T>::Insert(int i,T x)
{
    int count=1;
    Node<T> *p=first->t;//初始化结点,即代表p为第一个结点
    Node<T> *s=nullptr;//定义一个结点s
    while(p!=nullptr)//遍历链表
    {
        if(count==i-1)//i-1s'l
        {
            s=new Node<T>;s->data=x;//将我们要插入的元素值临时储存在s结点,s结点内数据域为x
            s->t=p->t;//s结点内指针域为p->t,即第i个结点地址
            p->t=s;//把第i-1个结点的指针域替换成s,相当于在第i-1与第i个结点之间插入s结点
            length+=1;
            break;
        }
        count+=1;
        p=p->t;
    }

}

template <typename T>
void LinkList<T>::Delete(int i)
{
    if(i>length) cout<<"Delete():删除位置超过了链表长度"<<endl;
    int count =1;
    Node<T> *p=first->t,*s=nullptr;
    while(p!=nullptr)
    {
        if(count==i-1)
        {
            s=p->t;//将第i个结点赋值给s结点,即s结点代表第i个结点
            p->t=s->t;//s->t代表第i+1个结点,p->t代表第i-1个结点的指针域,即将第i-1个结点的指针域改为指向第i+1个结点
            //这样相当于完成删除第i个结点
            length-=1;
            break;
        }
        count+=1;
        p=p->t;
    }
}

#endif // LINKLIST_H_INCLUDED

头文件SeqList.h

#ifndef SEQLIST_H_INCLUDED
#define SEQLIST_H_INCLUDED
//顺序表头文件
using namespace std;
const int Maxsize=100;//顺序表最大长度
template <typename T>
struct SeqList
{
    void SeqList0(T a[]);//创建长度为n的顺序表
    int Length();//返回数组长度
    T get(int i);//按位查找,查找第i个元素值
    T Find(T x);//按值查找,查找值为x的元素序号,返回-1代表未查找到
    void Insert(int i,T x);//插入操作,在第i个位置插入值为x的元素
    void Delete(int i);//删除操作,删除第i个元素
    void PrintList();//按序号依次输出各元素
    T MAX();//取表中最大的
    T MIN();//取表中最小的
    void Sort();//从小到大排序
    void Sort_reverse();//从大到小排序
private:
    T data[Maxsize];
    int length=0;
};

template <typename T>
void SeqList<T>::SeqList0(T a[])
{
    for(int i=0; i<Maxsize; i+=1)
    {
        if(a[i]<1e-300) break;//判断输入的值长度
        else length+=1;
    }
    if(length==Maxsize) cout<<"SeqList0():警告建议扩大表最大长度"<<endl;
    for(int i=0; i<length; i+=1)
    {
        data[i]=a[i];
    }
}

template <typename T>
int SeqList<T>::Length()
{
    return length;
}

template <typename T>
T SeqList<T>::get(int i)
{
    if (i<1||i>length) cout<<"get():超出表长度"<<endl;
    return data[i-1];
}

template <typename T>
T SeqList<T>::Find(T x)
{
    for(int i=0; i<length; i+=1)
    {
        if(data[i]==x)
        {
            return i+1;
            break;
        }
        else if(i==length-1)//最后一个循环完了都没有执行break,说明没查找到
        {
            return -1;
        }
    }
}

template <typename T>
void SeqList<T>::Insert(int i,T x)
{
    if(length==Maxsize) cout<<"Insert():溢出"<<endl;
    if(i<1||i>length+1) cout<<"Insert():插入位置错误"<<endl;
    for(int j=length-1; j>=i-1; j=j-1)
    {
        data[j+1]=data[j];//从最后的元素开始往后移,到要插入的地方停止
    }
    data[i-1]=x;
    length+=1;//更新表的长度
}

template <typename T>
void SeqList<T>::Delete(int i)
{
    if(i<1||i>length) cout<<"Delete():删除的位置不存在"<<endl;
    for(int j=i-1; j<length; j+=1)
    {
        data[j]=data[j+1];//删除之后,后面的数整体向前移
    }
    length-=1;
}

template <typename T>
void SeqList<T>::PrintList()
{
    for(int i=1; i<=length; i+=1)
    {
        cout<<get(i)<<" ";
    }
}

template <typename T>
T SeqList<T>::MAX()
{
    double z=data[0];
    for(int i=0; i<length; i+=1)
    {
        if(data[i]>z) z=data[i];
    }
    return z;
}

template <typename T>
T SeqList<T>::MIN()
{
    double z=data[0];
    for(int i=0; i<length; i+=1)
    {
        if(data[i]<z) z=data[i];
    }
    return z;
}

template <typename T>
void SeqList<T>::Sort()
{
    int a=999;//主要为了while能开始循环
    while(a!=0)
    {
        a=0;
        for(int i=0; i<length-1; i+=1)
        {
            if(data[i]>data[i+1])
            {
                double x=data[i];
                data[i]=data[i+1];
                data[i+1]=x;//冒泡排序
                a=a+1;//判断是否执行了if这个语句,没有执行则说明完成排序的,同时a值不会被改变恒为0,从而退出while循环
            }
        }
    }
}

template <typename T>
void SeqList<T>::Sort_reverse()
{
    double a=999;//目的主要是为了让while能开始循环
    while(a!=0)
    {
        a=0;
        for(int i=0; i<length-1; i+=1) //length是代表数组长度
        {
            if(data[i]<data[i+1])
            {
                //交换位置
                T x=data[i];
                data[i]=data[i+1];
                data[i+1]=x;
                a+=1;
            }
        }
    }
}
#endif // SEQLIST_H_INCLUDED

运行结果:

-----顺序表操作的实现-----
原始顺序表为:1 4 6 2 9 11 1
在第5个位置插入7为:1 4 6 2 7 9 11 1
删除第3个位置元素为:1 4 2 7 9 11 1
按位查找,查找第6个元素值为:11
最大值为:11
从小到大排序为:1 1 2 4 7 9 11 从大到小排序为:11 9 7 4 2 1 1
-----链表操作的实现-----
链表的长度为7
原始链表内具体内容:
1 0xf61a30      11 0xf61a10     9 0xf619f0      2 0xf619d0      6 0xf619b0      4 0xf61660      1 0
打印结束
获取第3个结点的元素值:9
查找元素值为6的结点序号:5
将22插入第3个结点:
1 0xf61a30      11 0xf61a70     22 0xf61a10     9 0xf619f0      2 0xf619d0      6 0xf619b0      4 0xf61660      1 0
打印结束
删除第5个结点:
1 0xf61a30      11 0xf61a70     22 0xf61a10     9 0xf619d0      6 0xf619b0      4 0xf61660      1 0
打印结束

Process returned 0 (0x0)   execution time : 0.030 s
Press any key to continue.

猜你喜欢

转载自blog.csdn.net/m0_62526778/article/details/129603698