线性表综合实验
一.实验目的
巩固线性表的数据结构的存储方法和相关操作,学会针对具体应用,使用线性表的相关知识来解决具体问题。
二.实验时间
准备时间为第3周到第4周,具体集中实验时间为第4周第2次课。2个学时。
三..实验内容
顺序表:
- <span style="font-size:18px;">SeqList(T score[],int n); //构造函数,建立一个长度为n的顺序表
- ~SeqList(){} //析构函数
- void insert(int i,T x); //插入操作,在位置i插入元素x
- T Delete(int i); //在位置i删除对应元素
- T get(int i); //按位查找,找位置i的元素
- int locate(T x); //按值查找,找数值为x的元素
- void print(); //遍历操作,按序号依次输出各元素</span>
- /*建立一个由n个学生成绩的顺序表,每一个学生的成绩信息由自己确定,实现数据的对表进行插入、删除、查找等操作。分别输出结果。*/
- template <typename T>
- class SeqList{
- public:
- SeqList(T score[],int n); //构造函数,建立一个长度为n的顺序表
- ~SeqList(){} //析构函数
- void insert(int i,T x); //插入操作,在位置i插入元素x
- T Delete(int i); //在位置i删除对应元素
- T get(int i); //按位查找,找位置i的元素
- int locate(T x); //按值查找,找数值为x的元素
- void print(); //遍历操作,按序号依次输出各元素
- private:
- T data[max]; //存放数据元素的数组
- int length; //线性表的长度
- };
- //构造函数
- template <class T>
- SeqList<T>::SeqList(T score[],int n)
- {
- if(n>max)throw"参数非法";
- for(int i=0;i<n;i++)
- data[i]=score[i];
- length=n;
- }
- //插入操作
- template <class T>
- void SeqList<T>::insert(int i,T x)
- {
- int j;
- if(length>max)throw"上溢";
- if(i<1||i>=max)throw"位置非法";
- for(j=length;j>=i;j--)
- data[j]=data[j-1];
- data[i-1]=x;
- length++;
- }
- //删除操作
- template <class T>
- T SeqList<T>::Delete(int i)
- {
- T p;int j;
- if(length==0)throw"下溢";
- if(i<1||i>=max)throw"位置非法";
- p=data[i-1];
- for(j=i;j<length;j++)
- data[j-1]=data[j];
- length--;
- return p;
- }
- //查找操作
- //按位查找
- template <class T>
- T SeqList<T>::get(int i)
- {
- if(i<1&&i>=length)throw"查找位置非法";
- else return data[i-1];
- }
- //按值查找
- template <class T>
- int SeqList<T>::locate(T x)
- {
- for(int i=0;i<length;i++)
- if(data[i]==x) return i+1; //返回元素序号
- return 0;
- }
- //输出操作
- template <class T>
- void SeqList<T>::print()
- {
- for(int i=0;i<length;i++)
- cout<<data[i]<<" ";
- }
- void main()
- {
- float score[8]={95.5,78,87.5,65,100,84.5,75,69.5};
- SeqList<float> student(score,8);
- cout<<" 学生数据结构成绩"<<endl;
- student.print();
- cout<<endl<<endl<<"在位置3插入成绩66,结果如下:"<<endl;
- student.insert(3,66);
- student.print();
- cout<<endl<<endl<<"在位置5删除成绩为:"<<student.Delete(5)<<endl<<"删除后结果如下:"<<endl;
- student.print();
- cout<<endl<<endl<<"位置6的成绩为:"<<student.get(6)<<endl;
- cout<<endl<<endl<<"成绩100所在位置为:"<<student.locate(100)<<endl;
- }
顺序表是线性结构,操作方便,容易理解
单链表:
- #include<iostream>
- using namespace std;
- template <typename T>
- struct Node
- {
- T data;
- Node<T> *next;
- };
- /*建立一个由n个学生成绩的顺序表,实现数据的对表进行插入、删除、查找等操作。分别输出结果。*/
- template <typename T>
- class LinkList{
- public:
- LinkList(); //无参构造函数,建立只有头结点的空链表
- LinkList(T score[],int n); //构造函数
- ~LinkList() //析构函数
- {
- Node<T> *q;
- while(first!=NULL)
- {
- q=first;
- first=first->next;
- delete q;
- }
- }
- void insert(int i,T x); //插入操作,在位置i插入元素x
- T Delete(int i);//删除操作,删除位置i的元素
- T get(int i);//按位查找
- int locate(T x); //按值查找
- void print();//输出操作
- private:
- Node<T> *first; //头指针
- };
- template<class T>
- LinkList<T>::LinkList()
- {
- first = new Node<T>;
- first->next = NULL;
- }
- template<typename T>
- LinkList<T>::LinkList(T score[],int n)
- {
- Node<T>*s;
- first=new Node<T>; first->next=NULL; //初始化一个空链表
- for(int i=0;i<n;i++)
- {
- s=new Node<T>;s->data=score[i]; //为每个数组元素建立一个结点
- s->next=first->next;first->next=s; //将结点s插入头结点之后
- }
- }
- template<typename T>
- void LinkList<T>::insert(int i,T x)
- {
- Node<T>*p,*s;int count;
- p=first;count=0;
- while(p!=NULL&&count<i-1)
- {
- p=p->next;
- count++;
- }
- if(p==NULL)throw"位置非法";
- else{
- s=new Node<T>;s->data=x;
- s->next=p->next;p->next=s;
- }
- }
- template<typename T>
- T LinkList<T>::Delete(int i)
- {
- Node<T> *q,*p; T x; int count;
- p=first;count=0; //注意P指针要指向头结点
- while(p!=NULL&&count<i-1) //此操作目的是找到i-1个结点
- {
- p=p->next;
- count++;
- }
- if(p==NULL||p->next==NULL)throw"位置"; //结点p不存在或p后继结点不存在
- else{
- q=p->next;x=q->data; //暂存被删结点
- p->next=q->next;
- delete q;
- return x;
- }
- }
- template<typename T>
- T LinkList<T>::get(int i)
- {
- Node<T>*p;int count;
- p=first->next;count=1;
- while(p!=NULL&&count<i)
- {p=p->next;count++;}
- if(p==NULL)throw"位置非法";
- else return p->data;
- }
- template<typename T>
- int LinkList<T>::locate(T x)
- {
- Node<T>*p;int count;
- p=first->next;count=1;
- while(p!=NULL)
- {
- if(p->data==x)return count;
- p=p->next;
- count++;
- }
- return 0;
- }
- template<typename T>
- void LinkList<T>::print()
- {
- Node<T>*p;
- p=first->next;
- while(p!=NULL)
- {cout<<p->data<<" ";;
- p=p->next;
- }
- }
- void main()
- {
- int score[5]={69,52,99,85,76};
- LinkList<int>student(score,5); //创建对象
- cout<<" 学生数据结构成绩"<<endl;
- student.print();
- cout<<endl<<endl<<"在位置3插入成绩66,结果如下:"<<endl;
- student.insert(3,66);
- student.print();
- cout<<endl<<endl<<"在位置2删除成绩为:"<<student.Delete(2)<<endl<<"删除后结果如下:"<<endl;
- student.print();
- cout<<endl<<endl<<"位置3的成绩为:"<<student.get(3)<<endl;
- cout<<endl<<endl<<"成绩99所在位置为:"<<student.locate(99)<<endl;
- }
双链表:
- #include<iostream>
- using namespace std;
- template <typename T>
- class Node
- {
- public:
- T data;
- Node<T> *prior;
- Node<T> *next;
- };
- template <typename T>
- class DLL {
- public:
- DLL();
- DLL(T score[], int n); //有参构造函数
- ~DLL(); //析构函数
- int Length(); //返回单链表长度
- void insert(int i, T x); //插入操作,在位置i插入元素
- T get(int i); //按位查找
- int locate(T x); //按值查找
- T Delete(int i); //删除操作
- void print(); //遍历操作
- private:
- Node<T> *first; //双链表的头指针
- int length; //链的长度计数
- };
- template <typename T>
- DLL<T>::DLL(T score[], int n)
- {
- length=0;
- first = new Node<T>;
- first->next = NULL;
- first->prior = NULL;
- for (int i = 0; i<n; i++)
- {
- Node<T> *s = new Node<T>;
- s->data = score[i];
- s->next = first->next;
- first->next = s;
- }
- }
- template <typename T>
- DLL<T>::~DLL()
- {
- while (first->next!=first->prior)
- {
- //临时指针,存储即将释放的节点的指针
- Node<T> *temp = first;
- //脱链
- first->prior->next = first->next;
- first->next -> prior = first->prior;
- //头指针后移
- first = first->next;
- //释放内存
- delete temp;
- }
- delete first;
- }
- template<typename T>
- int DLL<T>::Length()
- {
- Node<T> *p; int count;
- p=first->next;
- count=0;
- while(p!=NULL)
- {
- p=p->next;
- count++;
- }
- return length;
- }
- template <typename T>
- void DLL<T>::insert(int i,T x)
- {
- Node<T>*p,*s;int count;
- p=first;
- count=0;
- while(p!=NULL&&count<i-1)
- {
- p=p->next;
- count++;
- }
- if(p==NULL) throw"位置";
- else
- {
- s=new Node<T>;
- s->data=x;
- s->next=p->next;
- p->next=s;
- }
- }
- template <typename T>
- T DLL<T>::get(int i)
- {
- Node<T> *p;int count; count = 1;
- p = first->next;
- while (p != NULL&&count<i)
- {
- p = p->next; count++;
- }
- if (p == NULL)throw"位置非法";
- else return p->data;
- }
- template <typename T>
- int DLL<T>::locate(T x)
- {
- Node<T> *p; int count;
- p = first->next; count = 1;
- while (p!= NULL)
- {
- if (p->data == x) return count;
- p = p->next;
- count++;
- }
- return 0;
- }
- template <typename T>
- T DLL<T>::Delete(int i)
- {
- Node<T> *p,*q;
- p = first->next; int count, x; count = 1;
- while (p != NULL&&count<i-1)
- {
- p = p->next; count++;
- }
- if (p == NULL || p->next == NULL) throw"位置非法";
- else
- {
- q = p->next;
- x=q->data;
- if (p->next != NULL)
- {
- if(q->next!=NULL)
- q->next->prior = p;
- else
- {
- p->next=NULL;
- p->next = q->next;
- delete q;
- q = NULL;
- return x;
- }
- }
- p->next = q->next;
- delete q;
- q = NULL;
- return x;
- }
- }
- template <typename T>
- void DLL<T>::print()
- {
- Node<T> *p;
- p = first->next;
- while (p->next != NULL)
- {
- cout << p->data << " ";
- p = p->next;
- }
- cout << p->data << endl;
- }
- void main()
- {
- float score[8] = { 66.5,89.5,95,74.5,32.5,68,100,86.5 };
- DLL<float>student(score, 8);
- cout << " 学生数据结构成绩" << endl;
- student.print();
- cout << endl << endl << "在位置3插入成绩78,插入后结果如下:" << endl;
- student.insert(3,66);
- student.print();
- cout << endl << endl << "在位置2删除成绩为:" << student.Delete(2) <<" , "<< "删除后结果如下:" << endl;
- student.print();
- cout << endl << endl << "位置3的成绩为:" << student.get(3) << endl;
- cout << endl << endl << "成绩32.5所在位置为:" << student.locate(32.5) << endl;
- }
双链表相比单链表更加完善。
静态链表:
- #include<iostream>
- #include<string>
- using namespace std;
- //静态链表的储存结构
- const int Maxsize = 100;
- template<typename T>
- class Node {
- public:
- T data;
- int next; //存储指向下一个节点的数组下标
- };
- template <typename T>
- class SLL {
- public:
- SLL();//无参构造函数
- SLL(T score[],int n);//带参构造函数
- virtual ~SLL();//空的析构函数
- void print();//遍历操作
- T get(int i);//按位查找操作
- int Locate(T x);//按值查找操作
- void insert(int i, T x);//插入操作
- void Delete(int i);//删除操作
- private:
- Node<T> node[Maxsize];//节点
- int first;
- int avail;//指向空闲链的头指针
- int length;//当前静态链表的长度
- };
- template<typename T>
- SLL<T>::SLL(T score[],int n)
- {
- length = 0;
- for(int i = 0; i<Maxsize; i++)
- {
- node[i].next=i+1;
- }
- node[Maxsize - 1].next = -1;
- avail = 2;
- first = 1;
- node[first].next = -1;
- for (int j = n-1; j >=0; j--)
- {
- if (avail == -1)
- {
- break;
- }
- int s = avail;
- avail = node[avail].next;//空闲链的头指针后移
- node[s].data = score[j];//将score[j]填入下标为S的节点
- node[s].next = node[first].next;//将score[j]插到first后面
- node[first].next = s;
- length++;
- }
- }
- template<class T>
- SLL<T>::~SLL()
- {
- }
- template<typename T>
- void SLL<T>::print()
- {
- int s = node[first].next;
- for (int i = 1; i <= length; i++)
- {
- cout << node[s].data << " ";
- s = node[s].next;
- }
- }
- template<typename T>
- T SLL<T>::get(int i)
- {
- if(i<=0 || i>length) throw"位置非法";
- int p = first;
- for(int j = 0; j<i; j++)
- {
- p=node[p].next;
- }
- return node[p].data;
- }
- template<typename T>
- int SLL<T>::Locate(T x)
- {
- int count=0;
- int p = first;
- while(node[p].next != -1)
- {
- p=node[p].next;
- if(node[p].data == x) return count+1;
- count++;
- }
- return -1;
- }
- template<typename T>
- void SLL<T>::insert(int i, T x)
- {
- if(i<0||i>length) throw"位置非法";
- int p = first;
- for(int j = 1; j<i; j++)
- { p=node[p].next; /*或者p=node[p].next*/}
- int s = node[avail].next;
- node[avail].data = x;
- node[avail].next = node[p].next;
- node[p].next = avail;
- avail = s;
- length++;
- }
- template<typename T>
- void SLL<T>::Delete(int i)
- {
- if(i<0||i>length+1) throw"位置非法";
- int p = first;
- for(int j = 1;j<=i; j++)
- { p=node[p].next; }
- int q = node[p].next;
- T e = node[p].data;
- node[p].next = node[q].next;
- node[q].next = avail;
- avail = q;
- length--;
- }
- void main()
- {
- float score[5]={95.7,68.2,37.8,84.5,76.5};
- SLL<float> student(score,5);
- cout<<" 学生数据结构成绩"<<endl;
- student.print();
- cout<<endl<<endl<<"在位置3插入成绩66,结果如下:"<<endl;
- student.insert(3,66);
- student.print();
- cout<<endl<<endl<<"在位置4删除成绩 删除后结果如下:"<<endl;
- student.Delete(3);
- student.print();
- cout<<endl<<endl<<"位置2的成绩为:"<<student.get(2)<<endl;
- cout<<endl<<endl<<"成绩68.2所在位置为:"<<student.Locate(68.2)<<endl;
- }
静态链表使用数组来表示单链表,属于静态存储
间接寻址:
- #include<iostream>
- using namespace std;
- const int Maxsize = 100;
- template<typename T>
- struct Node {
- T data;
- Node<T> *next;
- };
- template<typename T>
- class inadd{
- public:
- inadd();//无参构造函数
- inadd(T score[],int n);//有参构造函数
- virtual ~inadd();//析构函数
- void print();//遍历操作
- T get(int i);//按位查找操作
- int Locate(T x);//按值查找操作
- void insert(int i,T x);//插入操作
- T Delete(int i);//删除操作
- bool changeList(int i, T x); //改变某一结点的值 i为节点的位置,x为替换的值
- private:
- Node<T> *first; //头指针
- int length; //结点数量
- Node<T> *address[Maxsize]; //结点指针数组
- };
- template<typename T>
- inadd<T>::inadd()
- {
- first=new Node<T>;
- first->next=NULL;
- }
- template<typename T>
- inadd<T>::inadd(T score[],int n)
- {
- if (n > Maxsize) throw("溢出");
- Node<T> *s;
- first = new Node<T>;first->next=NULL; //初始化一个空链表
- for(int i=n-1;i>=0;i--)
- {
- s=new Node<T>;s->data=score[i]; //为每个数组元素建立一个结点
- s->next=first->next;first->next=s; //将结点s插入头结点之后
- }
- }
- template<typename T>
- inadd<T>::~inadd() //析构函数
- {
- Node<T> *q;
- while(first!=NULL)
- {
- q=first;
- first=first->next;
- delete q;
- }
- }
- template<typename T>
- void inadd<T>::insert(int i,T x)
- {
- Node<T>*p,*s;int count;
- p=first;count=0;
- while(p!=NULL&&count<i-1)
- {
- p=p->next;
- count++;
- }
- if(p==NULL)throw"位置非法";
- s=new Node<T>;s->data=x;
- s->next=p->next;
- p->next=s;
- length++;
- }
- template<typename T>
- T inadd<T>::Delete(int i)
- {
- Node<T> *q,*p; T x; int count;
- p=first;count=0; //注意P指针要指向头结点
- while(p!=NULL&&count<i-1) //此操作目的是找到i-1个结点
- {
- p=p->next;
- count++;
- }
- if(p==NULL||p->next==NULL)throw"位置"; //结点p不存在或p后继结点不存在
- else{
- q=p->next;x=q->data; //暂存被删结点
- p->next=q->next;
- delete q;
- return x;
- }
- }
- template<typename T>
- T inadd<T>::get(int i)
- {
- Node<T>*p;int count;
- p=first->next;count=1;
- while(p!=NULL&&count<i)
- {p=p->next;count++;}
- if(p==NULL)throw"位置非法";
- else return p->data;
- }
- template<typename T>
- int inadd<T>::Locate(T x)
- {
- Node<T>*p;int count =1;
- p=first->next;
- while(p!=NULL)
- {
- if(p->data==x)return count;
- p=p->next;
- count++;
- }
- return 0;
- }
- template<typename T>
- void inadd<T>::print()
- {
- Node<T>*p;
- p=first->next;
- while(p!=NULL)
- {cout<<p->data<<" ";;
- p=p->next;
- }
- }
- void main()
- {
- float score[5]={69.3,52.6,99,85.7,76.9};
- inadd<float>student(score,5); //创建对象
- cout<<" 学生数据结构成绩"<<endl;
- student.print();
- cout<<endl<<endl<<"在位置3插入成绩66,结果如下:"<<endl;
- student.insert(3,66);
- student.print();
- cout<<endl<<endl<<"在位置2删除成绩为:"<<student.Delete(2)<<endl<<"删除后结果如下:"<<endl;
- student.print();
- cout<<endl<<endl<<"位置3的成绩为:"<<student.get(3)<<endl;
- cout<<endl<<endl<<"成绩76.9所在位置为:"<<student.Locate(76.9)<<endl;
- }
间接寻址也利用了数组,属于随机存储。
总结:
俗话说“实践是检验真理的唯一标准”。在课堂上短短的学习时间,并不能很好地对所学知识有很好的理解,相反,我们更需要在课后多花时间上机实验,才能更大程度地掌握所学知识的原理。
实验完成后,我们不能就此满足,更应该多花时间课后多看书,多理解。