实验内容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(包括建立空表,构造函数(头插法或尾插法二选一)、遍历操作、求长度、按位查找、按值查找、插入、删除、析构函数)。
源文件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.