贵州大学数据结构实验1-线性表及应用
桂电数据结构实验一-线性表
桂电数据结构实验一-线性表实验一线性表实验目的1、掌握线性表的逻辑结构和物理实现;2、掌握线性表的顺序存储结构和链式存储结构,熟悉对线性表的基本操作;3、在学有余力的情况下,掌握循环链表的实现及其基本操作;4、根据实验要求设计并完成程序,把理论的基本操作知识转化到实际的实践应用中。
课题一的具体实验内容1、构造元素类型为整型的线性表,将以下元素插入分别插入线性表:<34 56 20 9 15 5>2、查找表中是否存在元素20,实现元素20与元素9的交换;3、按照课题要求编写函数,实现线性表元素<34 56 9 20 15 5>的倒置,即倒置后的表应为< 5 15 20 9 56 34 >。
主程序代码#include<stdio.h>#include<stdlib.h>#define NULL 0struct node{int num;struct node *next;};void main(){int i,flag=1;struct node *L,*s,*p,*h,*q,*k,*p1,*temp;L=(node*)malloc(sizeof(struct node));p=L; printf("请输入\n");for(i=0;i<6;i++){s=(node*)malloc(sizeof(struct node));scanf("%d",&s->num);p->next=s;p=s;}p->next=NULL; //以上是链表的建立和输入//以下为a元素交换p=L;while(p->next->num!=20&&p->next->next!=NULL) p=p->next;if(p->next->next==NULL){printf("sorry,can not find!\n");flag=0;printf("原表括倒置后输出\n");}else if (p->next->num==20){flag=1;printf("find it!\n");}if(flag==1){h=p->next;p->next=p->next->next;h->next=p->next->next;p->next->next=h;//以下为链表括的输出printf("交换后输出\n");p=L->next;while(p!=NULL){printf("%d ",p->num);p=p->next;}printf("倒置后输出\n");}//以下为链表括的倒置p1=L->next;temp=p1->next;p1->next=NULL;p=temp;while(temp!=NULL){ p=p->next;//移动原链表的指针?temp->next=p1;L->next=temp;p1=temp;//需插入节点的指向移动temp=p;}//以下为链表输出p=L->next;while(p!=NULL){printf("%d ",p->num);p=p->next;}printf("\n");}。
数据结构实验报告-线性表(顺序表实现)
实验1:线性表(顺序表的实现)一、实验项目名称顺序表基本操作的实现二、实验目的掌握线性表的基本操作在顺序存储结构上的实现。
三、实验基本原理顺序表是由地址连续的的向量实现的,便于实现随机访问。
顺序表进行插入和删除运算时,平均需要移动表中大约一半的数据元素,容量难以扩充四、主要仪器设备及耗材Window 11、Dev-C++5.11五、实验步骤1.导入库和一些预定义:2.定义顺序表:3.初始化:4.插入元素:5.查询元素:6.删除元素:7.销毁顺序表:8.清空顺序表:9.顺序表长度:10.判空:11.定位满足大小关系的元素(默认小于):12.查询前驱:13.查询后继:14.输出顺序表15.归并顺序表16.写测试程序以及主函数对顺序表的每一个操作写一个测试函数,然后在主函数用while+switch-case的方式实现一个带菜单的简易测试程序,代码见“实验完整代码”。
实验完整代码:#include <bits/stdc++.h>using namespace std;#define error 0#define overflow -2#define initSize 100#define addSize 10#define compareTo <=typedef int ElemType;struct List{ElemType *elem;int len;int listsize;}L;void init(List &L){L.elem = (ElemType *) malloc(initSize * sizeof(ElemType)); if(!L.elem){cout << "分配内存失败!";exit(overflow);}L.len = 0;L.listsize = initSize;}void destroy(List &L){free(L.elem);L.len = L.listsize = 0;}void clear(List &L){L.len = 0;}bool empty(List L){if(L.len == 0) return true;else return false;}int length(List L){return L.len;}ElemType getElem(List L,int i){if(i < 1 || i > L.len + 1){cout << "下标越界!";exit(error);}return L.elem[i - 1];}bool compare(ElemType a,ElemType b) {return a compareTo b;}int locateElem(List L,ElemType e) {for(int i = 0;i < L.len;i++){if(compare(L.elem[i],e))return i;}return -1;}int check1(List L,ElemType e){int idx = -1;for(int i = 0;i < L.len;i++)if(L.elem[i] == e)idx = i;return idx;}bool check2(List L,ElemType e){int idx = -1;for(int i = L.len - 1;i >= 0;i--)if(L.elem[i] == e)idx = i;return idx;}int priorElem(List L,ElemType cur_e,ElemType pre_e[]) {int idx = check1(L,cur_e);if(idx == 0 || idx == -1){string str = "";str = idx == 0 ? "无前驱结点" : "不存在该元素";cout << str;exit(error);}int cnt = 0;for(int i = 1;i < L.len;i++){if(L.elem[i] == cur_e){pre_e[cnt ++] = L.elem[i - 1];}}return cnt;}int nextElem(List L,ElemType cur_e,ElemType next_e[]){int idx = check2(L,cur_e);if(idx == L.len - 1 || idx == - 1){string str = "";str = idx == -1 ? "不存在该元素" : "无后驱结点";cout << str;exit(error);}int cnt = 0;for(int i = 0;i < L.len - 1;i++){if(L.elem[i] == cur_e){next_e[cnt ++] = L.elem[i + 1];}}return cnt;}void insert(List &L,int i,ElemType e){if(i < 1 || i > L.len + 1){cout << "下标越界!";exit(error);}if(L.len >= L.listsize){ElemType *newbase = (ElemType *)realloc(L.elem,(L.listsize + addSize) * sizeof(ElemType));if(!newbase){cout << "内存分配失败!";exit(overflow);}L.elem = newbase;L.listsize += addSize;for(int j = L.len;j > i - 1;j--)L.elem[j] = L.elem[j - 1];L.elem[i - 1] = e;L.len ++;}void deleteList(List &L,int i,ElemType &e){if(i < 1 || i > L.len + 1){cout << "下标越界!";exit(error);}e = L.elem[i - 1];for(int j = i - 1;j < L.len;j++)L.elem[j] = L.elem[j + 1];L.len --;}void merge(List L,List L2,List &L3){L3.elem = (ElemType *)malloc((L.len + L2.len) * sizeof(ElemType)); L3.len = L.len + L2.len;L3.listsize = initSize;if(!L3.elem){cout << "内存分配异常";exit(overflow);}int i = 0,j = 0,k = 0;while(i < L.len && j < L2.len){if(L.elem[i] <= L2.elem[j])L3.elem[k ++] = L.elem[i ++];else L3.elem[k ++] = L2.elem[j ++];}while(i < L.len)L3.elem[k ++] = L.elem[i ++];while(j < L2.len)L3.elem[k ++] = L2.elem[j ++];}bool visit(List L){if(L.len == 0) return false;for(int i = 0;i < L.len;i++)cout << L.elem[i] << " ";cout << endl;return true;}void listTraverse(List L){if(!visit(L)) return;}void partion(List *L){int a[100000],b[100000],len3 = 0,len2 = 0; memset(a,0,sizeof a);memset(b,0,sizeof b);for(int i = 0;i < L->len;i++){if(L->elem[i] % 2 == 0)b[len2 ++] = L->elem[i];elsea[len3 ++] = L->elem[i];}for(int i = 0;i < len3;i++)L->elem[i] = a[i];for(int i = 0,j = len3;i < len2;i++,j++) L->elem[j] = b[i];cout << "输出顺序表:" << endl;for(int i = 0;i < L->len;i++)cout << L->elem[i] << " ";cout << endl;}//以下是测试函数------------------------------------void test1(List &list){init(list);cout << "初始化完成!" << endl;}void test2(List &list){if(list.listsize == 0)cout << "线性表不存在!" << endl;else{int len;ElemType num;cout << "选择插入的元素数量:" << endl;cin >> len;cout << "依次输入要插入的元素:" << endl;for(int i = 1;i <= len;i++){cin >> num;insert(list,i,num);}cout << "操作成功!" << endl;}}void test3(){if(L.listsize == 0)cout << "线性表不存在!" << endl;else{cout << "请输入要返回的元素的下标" << endl;int idx;cin >> idx;cout << "线性表中第" << idx << "个元素是:" << getElem(L,idx) << endl;}}void test4(){if(L.listsize == 0)cout << "线性表不存在!" << endl;else{int idx;ElemType num;cout << "请输入要删除的元素在线性表的位置" << endl;cin >> idx;deleteList(L,idx,num);cout << "操作成功!" << endl << "被删除的元素是:" << num << endl; }}void test5(){if(L.listsize == 0)cout << "线性表不存在!" << endl;else{destroy(L);cout << "线性表已被销毁" << endl;}}void test6(){if(L.listsize == 0)cout << "线性表不存在!" << endl;else{clear(L);cout << "线性表已被清空" << endl;}}void test7(){if(L.listsize == 0)cout << "线性表不存在!" << endl;else cout << "线性表的长度现在是:" << length(L) << endl;}void test8(){if(L.listsize == 0)cout << "线性表不存在!" << endl;else if(empty(L))cout << "线性表现在为空" << endl;else cout << "线性表现在非空" << endl;}void test9(){if(L.listsize == 0)cout << "线性表不存在!" << endl;else{ElemType num;cout << "请输入待判定的元素:" << endl;cin >> num;cout << "第一个与目标元素满足大小关系的元素的位置:" << locateElem(L,num) << endl;}}void test10(){if(L.listsize == 0)cout << "线性表不存在!" << endl;else{ElemType num,num2[initSize / 2];cout << "请输入参照元素:" << endl;cin >> num;int len = priorElem(L,num,num2);cout << num << "的前驱为:" << endl;for(int i = 0;i < len;i++)cout << num2[i] << " ";cout << endl;}}void test11(){if(L.listsize == 0)cout << "线性表不存在!" << endl;else{ElemType num,num2[initSize / 2];cout << "请输入参照元素:" << endl;cin >> num;int len = nextElem(L,num,num2);cout << num << "的后继为:" << endl;for(int i = 0;i < len;i++)cout << num2[i] << " ";cout << endl;}}void test12(List list){if(L.listsize == 0)cout << "线性表不存在!" << endl;else{cout << "输出线性表所有元素:" << endl;listTraverse(list);}}void test13(){if(L.listsize == 0)cout << "初始线性表不存在!" << endl; else{List L2,L3;cout << "初始化一个新线性表" << endl;test1(L2);test2(L2);cout << "归并两个线性表" << endl;merge(L,L2,L3);cout << "归并成功!" << endl;cout << "输出合并后的线性表" << endl;listTraverse(L3);}}void test14(){partion(&L);cout << "奇偶数分区成功!" << endl;}int main(){std::ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);int op = 0;while(op != 15){cout << "-----------------menu--------------------" << endl;cout << "--------------1:初始化------------------" << endl;cout << "--------------2:插入元素----------------" << endl;cout << "--------------3:查询元素----------------" << endl;cout << "--------------4:删除元素----------------" << endl;cout << "--------------5:销毁线性表--------------" << endl;cout << "--------------6:清空线性表--------------" << endl;cout << "--------------7:线性表长度--------------" << endl;cout << "--------------8:线性表是否为空----------" << endl;cout << "--------------9:定位满足大小关系的元素--" << endl;cout << "--------------10:查询前驱---------------" << endl;cout << "--------------11:查询后继---------------" << endl;cout << "--------------12:输出线性表-------------" << endl;cout << "--------------13:归并线性表-------------" << endl;cout << "--------------14:奇偶分区---------------" << endl;cout << "--------------15: 退出测试程序-----------" << endl;cout << "请输入指令编号:" << endl; if(!(cin >> op)){cin.clear();cin.ignore(INT_MAX,'\n');cout << "请输入整数!" << endl;continue;}switch(op){case 1:test1(L);break;case 2:test2(L);break;case 3:test3();break;case 4:test4();break;case 5:test5();break;case 6:test6();break;case 7:test7();break;case 8:test8();break;case 9:test9();break;case 10:test10();break;case 11:test11();break;case 12:test12(L);break;case 13:test13();break;case 14:test14();break;case 15:cout << "测试结束!" << endl;default:cout << "请输入正确的指令编号!" << endl;}}return 0;}六、实验数据及处理结果1.初始化:2.插入元素3.查询元素(返回的是数组下标,下标从0开始)4.删除元素(位置从1开始)5.销毁顺序表6.清空顺序表7.顺序表长度(销毁或清空操作前)8.判空(销毁或清空操作前)9.定位满足大小关系的元素(销毁或清空操作前)说明:这里默认找第一个小于目标元素的位置且下标从0开始,当前顺序表的数据为:1 4 2 510.前驱(销毁或清空操作前)11.后继(销毁或清空操作前)12.输出顺序表(销毁或清空操作前)13.归并顺序表(销毁或清空操作前)七、思考讨论题或体会或对改进实验的建议通过本次实验,我掌握了定义线性表的顺序存储类型,加深了对顺序存储结构的理解,进一步巩固和理解了顺序表的基本操作,如建立、查找、插入和删除等。
实验一 线性表的操作及应用
{
p=p->next;
++j;
}
if ( !p||j>i )
{
printf("参数 i 错或单链表不存在");
return (NULL);
} /*第i个结点不存在*/
return (p);
}
int Insert_LinkList( LinkList H, int i, DataType x)
scanf("%d%d",&n,&m);
for(j=0;j<n;j++)
{
printf("请输入要插入的第%d个元素:",j+1);
scanf("%d",&x);
y=Insert_LinkList( L,m,x);
if(y==1)
{
y=0;
printf("成功插入第%d个元素。\n",j+1);
}
}
代码:
#include <stdio.h>
#include <malloc.h>
typedef int DataType;
typedef struct node{
DataType data; /*每个元素数据信息*/
struct node *next; /*存放后继元素的地址*/
} LNode, *LinkList;
y=0;
/*(将单链表逆置,并输出逆置后单链表中的元素)*/
InvertList(L);
y=Print_LinkList(L);
实验1线性表及其应用
实验1 线性表及其应用实验性质:验证性实验学时:2学时一、实验目的1.掌握线性表的顺序存储结构在计算机的表示方法及其基本操作的实现;2.掌握线性表的链式存储结构在计算机的表示方法及其基本操作的实现;3.能够利用线性表结构对实际问题进行分析建模,利用计算机求解。
二、实验预备知识1.复习C/C++语言相关知识(如:结构体的定义、typedef的使用、函数的定义、调用及参数传递方式);2.阅读并掌握顺序表与链表的类型定义及其查找、插入、删除等基本操作。
三、实验内容1.理解并分别用顺序表、链表的操作运行下列程序:#include <iostream>using namespace std;#include "Status.h"typedef int ElemType;#include "SqList.h" //用#include "LinkList.h"替换void main(){SqList L; //用LinkList L;替换,与#include "LinkList.h"配合int n,i;ElemType e;InitList(L);cout<<"\nL=";ListTraverse(L);cout<<"\n请设置将向线性表L中输入的元素个数:";cin>>n;CreateList(L,n);cout<<"\nL=";ListTraverse(L);cout<<"\nL的表长为:"<<ListLength(L)<<endl;cout<<"\n请输入想要获取的元素位序:";cin>>i;if(GetElem(L,i,e)) cout<<"\n第"<<i<<"个元素为:"<<e<<endl;else cout<<"\n第"<<i<<"个元素不存在!"<<endl;cout<<"\n请输入要查找的元素:";cin>>e;if(i=LocateElem(L,e)) cout<<"\n元素"<<e<<"的位置为:"<<i<<endl;else cout<<"\n元素"<<e<<"不存在!"<<endl;cout<<"\n请输入插入位置和所插入元素:";cin>>i>>e;if(ListInsert(L,i,e)){cout<<"\nL=";ListTraverse(L);}else cout<<"\n插入操作失败!"<<endl;cout<<"\n请输入被删元素的位置:";cin>>i;if(ListDelete(L,i,e)) cout<<"\n被删元素为:"<<e<<endl;else cout<<"\n删除操作失败!"<<endl;cout<<"\nL=";ListTraverse(L);}本题目说明:(1)头文件Status.h的内容如下:#define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define INFEASIBLE -1#define OVERFLOW -2typedef int Status;(2)头文件SqList.h(内容包括顺序表的结构定义及基本操作实现)。
数据结构实验一-线性表
数据结构实验⼀-线性表实验⼀线性表⼀、实验⽬的1、深刻理解线性结构的特点,以及在计算机内的两种存储结构。
2、熟练掌握线性表的顺序存储结构和链式存储结构,及其它们的基本操作,重点掌握查找、插⼊和删除等操作。
⼆、实验要求1、认真阅读程序,将未完成的代码补全(红⾊部分)。
2、上机调试,并运⾏程序。
3、保存和截图程序的运⾏结果,并结合程序进⾏分析。
三、实验内容和基本原理1、实验1.1 顺序表的操作利⽤顺序表存储⽅式实现下列功能(见参考程序1):1)通过键盘输⼊数据建⽴⼀个线性表,并输出该线性表。
如,依次输⼊元素25,21,46,90,12,98。
2)根据屏幕菜单的选择,进⾏数据的插⼊、删除和查找,并在插⼊或删除数据后,再输出线性表。
如,在第2个位置上插⼊元素43,然后输出顺序表。
删除顺序表第4个元素,输出改变的顺序表。
3)在屏幕菜单中选择0,结束程序的运⾏。
基本原理:在顺序表的第i个位置上插⼊⼀个元素时,必须先将线性表的第i个元素之后的所有元素依次后移⼀个位置,以便腾空⼀个位置,在把新元素插⼊到该位置。
当要删除第i个元素时,只需将第i个元素之后的所有元素前移⼀个位置。
程序代码(蓝⾊为补充的语句)://* * * * * * * * * * * * * * * * * * * * * * * *//*PROGRAM :顺序结构的线性表 *//*CONTENT :建⽴,插⼊,删除,查找 *//*编程语⾔: Visual c++ 6.0 *//* * * * * * * * * * * * * * * * * * * * * *#include#include#define MAXSIZE 20typedef int ElemType; //数据元素的类型typedef struct{ElemType a[MAXSIZE];int length;}SqList; //顺序存储的结构体类型SqList a,b,c;//函数声明void creat_list(SqList *L);void out_list(SqList L);void insert_sq(SqList *L,int i,ElemType e); ElemType delete_sq(SqList *L,int i);int locat_sq(SqList L,ElemType e);//主函数void main(){int i,k,loc;ElemType e,x;char ch;do {printf("\n\n\n");printf("\n 吴肖遥20151681310131");printf("\n 1.建⽴线性表");printf("\n 2.插⼊元素");printf("\n 3.删除元素");printf("\n 4.查找元素");printf("\n 0.结束程序运⾏");printf("\n =====================");printf("\n 请输⼊要执⾏的操作: ");scanf("%d",&k);switch(k){case 1:{creat_list(&a);out_list(a);}break;case 2:{printf("\n请输⼊插⼊位置: ",a.length+1); scanf("%d",&i);printf("请输⼊要插⼊的元素值: ");scanf("%d",&e);insert_sq(&a,i,e);out_list(a);}break;case 3:{printf("\n请输⼊要删除元素的位置: ",a.length); scanf("%d",&i);x=delete_sq(&a,i);out_list(a);if(x!=-1)printf("\n删除的元素为:%d\n",x);else printf("要删除的元素不存在!");}break;case 4:{printf("\n请输⼊要查找的元素值:");scanf("%d",&e);loc=locat_sq(a,e);if(loc==-1)printf("\n未找到指定元素!");elseprintf("\n已找到,元素的位置是: %d ",loc);}break;}/*switch*/}while(k!=0);printf("\n 按回车键,返回...\n");ch=getchar();}/*main*///建⽴线性表void creat_list(SqList *L){int i;printf("请输⼊线性表的长度: ");scanf("%d",&L->length);for(i=0;ilength;i++){printf("数据 %d =",i);scanf("%d",&(L->a[i]));}}//输出线性表void out_list(SqList L){int i;for(i=0;i<=L.length-1;i++)printf("%10d",L.a[i]);}//在线性表的第i个位置插⼊元素evoid insert_sq(SqList *L,int i,ElemType e){int j;if(L->length==MAXSIZE)printf("线性表已满!\n");else {if(i<1||i>L->length+1)printf("输⼊位置错!\n");else {for(j=L->length-1;j>=i-1;j--)L->a[j+1]=L->a[j];L->a[j+1]=e;/*将未完成的代码补全,提⽰:此处添加⼀条语句,将被删除的元素值赋给e*/ L->length++;}}}//删除第i个元素,返回其值ElemType delete_sq(SqList *L,int i){ElemType x;int j;if(L->length==0)printf("空表!\n");else if(i<1||i>L->length){printf("输⼊位置错!\n");x=-1;}else{x=L->a[i-1];for(j=i;j<=L->length-1;j++)L->a[j-1]=L->a[j];/*将未完成的代码补全,提⽰:此处添加⼀条语句,将被删除元素之后的元素左移。
数据结构实验-线性表及其实现栈和队列及其应用
数据结构实验报告一实验名称:线性表及其实现栈和队列及其应用1 实验目的及实验要求1.线性表目的要求:(1)熟悉线性表的基本运算在两种存储结构(顺序结构和链式结构)上的实现,以线性表的各种操作(建立、插入、删除等)的实现为实验重点;(2)通过本次实验帮助学生加深对顺序表、链表的理解,并加以应用;(3)掌握循环链表和双链表的定义和构造方法2.栈和队列目的要求:(1)掌握栈和队列这两种特殊的线性表,熟悉它们的特性,在实际问题背景下灵活运用它们;(2)本实验训练的要点是“栈”的观点及其典型用法;(3)掌握问题求解的状态表示及其递归算法,以及由递归程序到非递归程序的转化方法。
2实验内容及实验步骤(附运行结果截屏)1.线性表实验内容:(1)编程实现线性表两种存储结构(顺序存储、链式存储)中的基本操作的实现(线性表的创建、插入、删除和查找等),并设计一个菜单调用线性表的基本操作。
(2)建立一个按元素递增有序的单链表L,并编写程序实现:a)将x插入其中后仍保持L的有序性;b)将数据值介于min和max之间的结点删除,并保持L的有序性;c)(选做)将单链表L逆置并输出;(3)编程实现将两个按元素递增有序的单链表合并为一个新的按元素递增的单链表。
注:(1)为必做题,(2)~(3)选做。
2.栈和队列实验内容:(1)编程实现栈在两种存储结构中的基本操作(栈的初始化、判栈空、入栈、出栈等);(2)应用栈的基本操作,实现数制转换(任意进制);(3)编程实现队列在两种存储结构中的基本操作(队列的初始化、判队列空、入队列、出队列);(4)利用栈实现任一个表达式中的语法检查(括号的匹配)。
(5)利用栈实现表达式的求值。
注:(1)~(2)必做,(3)~(5)选做。
实验步骤:先编写线性表和栈和队列的类模板,实现各自的基础结构,之后按照要求编写适当的函数方法(公共接口),最后完成封装。
编写主函数直接调用即可。
核心代码://LinearList.h 顺序表//类的声明1.template<class T>2.class LinearList3.{4.public:5.LinearList(int sz = default_size);6.~LinearList();7.int Length()const; //length of the linear8.int Search(T x)const; //search x in the linear and return its order number9.T GetData(int i)const; //get i th order's data10.bool SetData(int i,T x); //change i th order's data to x11.bool DeleteData(int i);12.bool InsertData(int i,T x);13.void output(bool a,int b,int c); //print the linear14.void ReSize(int new_size);15.16.private:17.T *data;18.int max_size,last_data;19.};//构造函数1.template<class T>2.LinearList<T>::LinearList(int sz)3.{4.if(sz>0)5.{6.max_size = sz;st_data=-1;8.data=new T[max_size];9.if(data == NULL)10.{11.cerr<<"Memory creat error!"<<endl;12.exit(1);13.}14.}15.else16.{17.cerr<<"Size error!"<<endl;18.exit(1);19.}20.}//Qlist.h 链式表//模板类的声明1.template<class T>2.struct LinkNode3.{4.T data;5.LinkNode<T> *link;6.LinkNode(LinkNode<T> *ptr = NULL)7.{8.link = ptr;9.}10.LinkNode(const T item,LinkNode<T> *ptr = NULL)11.{12.data = item;13.link = ptr;14.}15.};16.17.template<class T>18.class Qlist: public LinkNode<T>19.{20.public:21.Qlist();22.Qlist(const T x);23.Qlist(Qlist<T>&L);24.~Qlist();25.void MakeEmpty();26.int Length()const; //length of the linear27.int Search(T x)const; //search x in the linear and return its order number28.LinkNode<T> *Locate(int i);29.T GetData(int i); //get i th order's data30.bool SetData(int i,T x); //change i th order's data to x31.bool DeleteData(int i);32.bool InsertData(int i,T x);33.void output(bool a,int b,int c); //print the linear34.35.protected:36.LinkNode<T> *first;37.};//构造函数1.template<class T>2.Qlist<T>::Qlist(Qlist<T>&L)3.{4.T value;5.LinkNode<T>*src = L.getHead();6.LinkNode<T>*des = first = new LinkNode<T>;7.while(src->link != NULL)8.{9.value = src->link->data;10.des->link = new LinkNode<T>(value);11.des = des->link;12.src = src->link;13.}14.des->link = NULL;15.}截屏:3 实验体会(实验遇到的问题及解决方法)刚开始的时候本想先写线性表的类模板然后分别进行继承写顺序表和链式表甚至是以后的栈和队列。
数据结构实验一:线性表的应用
数据结构实验报告实验一线性表的应用一、实验目的:1.掌握线性表的两种存储结构及实现方式;2.熟练掌握顺序表和链表的建立、插入和删除的算法。
二、实验要求:1.C完成算法设计和程序设计并上机调试通过。
2.撰写实验报告,提供实验结果和数据。
3.写出算法设计小结和心得。
三、实验内容:1.用顺序表表示集合,编写程序以实现集合的交、并、差运算。
2.设带头结点的单链表ha和hb中结点数据域值按从小到大顺序排列,且各自链表内无重复的结点,要求:(1)建立两个按升序排列的单链表ha和hb。
(2)将单链表ha合并到单链表hb中,且归并后的hb链表内无重复的结点,结点值仍保持从小到大顺序排列。
(3)输出合并后单链表hb中每个结点的数据域值。
四、程序源代码:1.#include<stdio.h>#include<stdlib.h>#define LIST_INIT_CAPACITY 100 typedef int ElementType;typedef struct List{ElementType elem[LIST_INIT_CAPACITY]; int nLength;}SqList;void init(struct List*L)//初始化顺序表{if(L)L->nLength=0;}int visit(SqList*L,ElementType e)//遍历顺序表{for(int i=0;i<L->nLength;i++){if(L->elem[i]==e){return 0;break;}elsecontinue;return 1;}}SqList*jiao(SqList*L1,SqList*L2,SqList*L3)//求两个集合的交集{int n=0;for(int i=0;i<L1->nLength;i++){for(int j=0;j<L2->nLength;i++){if(L1->elem[i]==L2->elem[j]){L3->elem[n]=L1->elem[i];n++;}elsecontinue;}}printf("集合的交集:\n");return L3;}SqList*bing(SqList*L1,SqList*L2,SqList*L3)//求两个集合的并集{int j=0;for (int i=0;i<L1->nLength;i++){if (visit(L2,L1->elem[i])){L3->elem[j]=L1->elem[i];L3->nLength++;j++;}elsecontinue;}printf("集合的并集:\n");return L3;}SqList*cha(SqList*L1,SqList*L2,SqList*L3)//求两个集合的差集{int j=0;for(int i=0;i<L1->nLength;i++){if(visit (L2,L1->elem[i])){L3->elem[j]=L1->elem[i];j++;L3->nLength++;}elsecontinue;}printf("集合的差集:\n");return L3;}void show(SqList *list)//显示线性表元素{for (int i=0;i<list->nLength;i++){printf(" %d",list->elem[i]);}printf("\n");}void main(){SqList*list1,*list2,*list3;list1=(SqList*)malloc(sizeof(SqList));list2=(SqList*)malloc(sizeof(SqList));list3=(SqList*)malloc(sizeof(SqList));init(list1);init(list2);init(list3);intstr1[6]={1,2,3,4,5,6},str2[7]={1,3,4,5,7,9,10};for(int i=0;i<6;i++){list1->elem[i]=str1[i];list1->nLength=i+1;}for(i=0;i<7;i++){list2->elem[i]=str2[i];list2->nLength++;}printf("初始集合:\n");show(list1);show(list2);list3=jiao(list1,list2,list3);show(list3);init(list3);list3=bing(list1,list2,list3);show(list3);init(list3);list3=cha(list1,list2,list3);show(list3);}2.#include <stdio.h>#include<stdlib.h>typedef int ElementType;typedef struct ListNode{ElementType data;struct ListNode *next;}sLinkList;sLinkList*create(ElementType i)//创建接点{sLinkList *p;p=(sLinkList*)malloc(sizeof(sLinkList));if(!p)exit(0);elsep->data=i;return p;}void anotherorder(sLinkList*head){sLinkList*P;P=head->next;if(head!=NULL)//头指针不为空{while (P->next!=NULL){sLinkList*q;//p的后继指针sLinkList*t;q=P->next;t=P->next->next;q->next=head->next;head->next=q;P->next=t;}}}void print(sLinkList*head)//输出链表{if(head==NULL){exit(0);}sLinkList*p=head->next;while(p!=NULL){printf("%4d",p->data);p=p->next;}printf("\n");}void hebing(sLinkList *p,sLinkList *q,sLinkList *l)//将两个链表合并{ sLinkList*z;q=q->next;l=l->next;while(q!=NULL&&l!=NULL){if(q->data>l->data){z=create(l->data);p->next=z;z->next=NULL;p=z;l=l->next;}elseif(q->data<l->data){z=create(q->data);p->next=z;z->next=NULL;p=z;q=q->next;}elseif(q->data==l->data){for(int i=0;i<2;i++){z=create(q->data);p->next=z;z->next=NULL;p=z;}q=q->next;l=l->next;}}if(q==NULL){while (l!=NULL){z=create(l->data);p->next=z;z->next=NULL;p=z;l=l->next;}}if(l==NULL){while (q!=NULL){z=create(q->data);p->next=z;z->next=NULL;p=z;q=q->next;}}printf("合并后:\n");}void deletelist(sLinkList*p)//删除多余元素节点{if(p!=NULL)p=p->next;sLinkList*q;//中间指针while (p!=NULL){int i=p->data;sLinkList*head=p;while (head->next!=NULL){if(i==head->next->data){q=head->next;head->next=q->next;free(q);}elsehead=head->next;}p=p->next;}printf("最终结果:\n");}void main(){sLinkList *ha; ha=(sLinkList*)malloc(sizeof(ListNode)); if(ha!=NULL)//判空{ha->next=NULL;ha->data=-1;}sLinkList *p;sLinkList *q=ha;int a[5]={2,4,6,8,10};for (int i=0;i<5;i++){p=create(a[i]);q->next=p;p->next=NULL;q=p;}printf("初始:\n");print(ha);sLinkList *hb;hb=(sLinkList*)malloc(sizeof(ListNode)); if(hb!=NULL)//判空{hb->next=NULL;hb->data=-1;}q=hb;int b[6]={1,4,5,8,9,10};for (i=0;i<6;i++){p=create(b[i]);q->next=p;p->next=NULL;q=p;}print(hb);//构建ha,hbsLinkList *hc;hc=(sLinkList*)malloc(sizeof(ListNode)); hebing(hc,ha,hb);print(hc);deletelist(hc);print(hc);}五、测试结果:1.2.六、小结(包括收获、心得体会、存在的问题及解决问题的方法、建议等)经过这次实验,我对线性表的两种形式顺序表和链表有了进一步的了解,对线性表之间的运算及线性表的简单应用有了更深的体会。
数据结构实验(1)线性表及其应用
计算机系数据结构实验报告(1)实验目的:帮助学生掌握线性表的基本操作在顺序和链表这两种存储结构上的实现,尤以链表的操作和应用作为重点。
问题描述:1、构造一个空的线性表L。
2、在线性表L的第i个元素之前插入新的元素e;3、在线性表L中删除第i个元素,并用e返回其值。
实验要求:1、分别利用顺序和链表存储结构实现线性表的存储,并设计出在不同的存储结构中线性表的基本操作算法。
2、在实验过程中,对相同的操作在不同的存储结构下的时间复杂度和空间复杂度进行分析。
算法分析:由于两种存储结构都用来创建线性结构的数据表,可采用相同的输出模式和整体结构类似的算法,如下:v1.0 可编辑可修改实验内容和过程:顺序存储结构线性表程序清单://顺序存储结构线性表的插入删除#include <iostream>#include <>using namespace std;# define LISTSIZE 100# define CREMENTSIZE 10typedef char ElemType; //定义数据元素类型为字符型typedef struct {ElemType *elem; //数据元素首地址int len; //当前元素个数int listsize; //当前存储最大容量}SqList;//构造一个空的线性表Lint InitList(SqList &L){=(ElemType *)malloc(LISTSIZE*sizeof(ElemType));if (! exit(-2); //分配空间失败=0;=LISTSIZE;}//在顺序线性表L中第i个位置之前插入新的元素eint ListInsert(SqList &L,int i,ElemType e){if (i<1||i>+1) return -1; //i值不合法if >={ElemType *newelem=(ElemType *)realloc,+CREMENTSIZE)*sizeof(ElemType));//存储空间已满,增加分配if(!newelem) exit (-2); //分配失败=newelem;+=CREMENTSIZE;}ElemType *q=&[i-1]) ;for (ElemType *p=&[]);p>=q;--p) *(p+1)=*p; //插入位置及其后的元素后移 *q=e; ++;return 1;}//在顺序线性表L中删除第i个元素,并用e返回其值int ListDelete(SqList &L,int i,ElemType&e){if (i<1||i> return -1; //i值不合法ElemType *p=&[i-1]);e=*p; ElemType*q=+;for (++p;p<=q+1;++p) *(p-1)=*p; //被删除元素之后的元素前移;return 1;}int main (){SqList L; char e,ch;int i,j,state;InitList(L); //构造线性表printf("请输入原始数据(字符串个数0~99):L="); //数据初始化gets;for ( j=1;[j-1]!='\0';j++) =j; //获取表长[j]='\0';printf("操作:插入(I)还是删除(D)\n"); //判断进行插入还是删除操作AGAIN:cin>>ch;if(ch=='I'){cout<<"插在第几个元素之前:"; //插入操作cin>>i; cout<<"输入要插入的新元素:";cin>>e;cout<<endl;printf("输入数据:L=(%s) ListInsert(L,%d,%c)",,i,e);state=ListInsert (L,i,e);}else if (ch=='D'){cout<<"删除第几个元素:"; //删除操作cin>>i;cout<<endl;printf("输入数据:L=(%s) DeleteList(L,%d,e)",,i);state=ListDelete(L,i,e);}else goto AGAIN; //操作指示符输入错误处理cout<<endl<<"正确结果:";if(state==-1) cout<<"ERROR,";printf("L=(%s) ",; //输出结果if(ch=='D'&&state!=-1) cout<<",e="<<e;}链式存储结构线性表程序清单:// - - - - -单链存储结构线性表的插入删除 - - - - -#include <iostream>#include <>using namespace std;#define null 0typedef char ElemType; //定义数据元素类型为字符型typedef struct LNode{ElemType data;struct LNode *next;}LNode,*LinkList;int GetElem(LinkList L,int i,ElemType &e) //获取第i个元素的值 {LinkList p;int j;p=L->next; j=1;while(p&&j<i){p=p->next; ++j; //寻找第i个元素}if(!p||j>i) return -1; //寻找失败e=p->data;return 1;}int ListInsert(LinkList &L,int i,ElemType e){//在带头结点的单链线性表L中第i个元素之前插入元素eLinkList p,s; int j;p=L;j=0;while(p&&j<i-1) {p=p->next;++j;}if(!p||j>i-1) return -1;s=(LinkList) malloc( sizeof(LNode));s->data=e;s->next=p->next;p->next=s;return 1;}int ListDelete(LinkList&L,int i,ElemType&e){//在带头结点的单链线性表L中,删除第i个元素,并由e返回其值LinkList p,q; int j;p=L;j=0;while(p->next&&j<i-1){p=p->next;++j;}if(!(p->next)||j>i-1) return -1;q=p->next;p->next=q->next;e=q->data;free(q);return 1;}int newdata(LinkList&L,char *ch){int k;printf("请输入原始数据(字符串个数0~99):L="); //数据初始化gets(ch);for (k=0;ch[k]!='\0';k++) ListInsert(L,k+1, ch[k]); //将初始化数据插入链表L中cout<<"OK"<<endl;return k; //返回链表中的元素个数}int main (){char *ch;ch=(char *)malloc(100*sizeof(char)); //定义数组用来辅助数据初始化LinkList L; //头指针LNode head; //头结点L=&head; =null;int i,k,state; char e,CH,f;k=newdata(L,ch); //调用函数使链表数据初始化=k; //将元素个数存入头结点的数据域printf("操作:插入(I)还是删除(D)\n"); //判断进行插入还是删除操作AGAIN:cin>>CH;if(CH=='I'){cout<<"插在第几个元素之前:"; //插入操作cin>>i; cout<<"输入要插入的新元素:";cin>>e;cout<<endl;printf("输入数据:L=(%s) ListInsert(L,%d,%c)",ch,i,e);state=ListInsert(L,i,e);++;}else if (CH=='D'){cout<<"删除第几个元素:"; //删除操作cin>>i;cout<<endl;printf("输入数据:L=(%s) DeleteList(L,%d,e)",ch,i);state=ListDelete(L,i,e);--;}else goto AGAIN; //操作指示符输入错误处理cout<<endl<<"正确结果:";if(state==-1) cout<<"ERROR,"; //输出结果cout<<"L=(";for(int m=1;>=m;m++) //一一输出数据{GetElem(L,m,f);cout<<f;}cout<<")";if(CH=='D'&&state!=-1) cout<<",e="<<e; //删除操作反馈e }实验结果:由于两个程序的输出模式相同,在此只列一组测试数据:L = () ListInsert (L, 1, 'k')L = (EHIKMOP) ListInsert (L, 9, 't')L = (ABCEHKNPQTU) ListInsert(L, 4, 'u') L = () ListDelete (L, 1, e)L = (DEFILMNORU) ListDelete_Sq(L, 5, e) L = (CD) ListDelete_Sq(L, 1, e)测试过程中所注意到的问题主要还是输出与输入界面的问题,通过灵活使用cout和cin函数来不断改进。
《数据结构》实验报告模板(附实例)--实验一线性表的基本操作实现
《数据结构》实验报告模板(附实例)---实验一线性表的基本操作实现实验一线性表的基本操作实现及其应用一、实验目的1、熟练掌握线性表的基本操作在两种存储结构上的实现,其中以熟悉各种链表的操作为重点。
2、巩固高级语言程序设计方法与技术,会用线性链表解决简单的实际问题。
二、实验内容√ 1、单链表的表示与操作实现 ( * )2、约瑟夫环问题3、Dr.Kong的艺术品三、实验要求1、按照数据结构实验任务书,提前做好实验预习与准备工作。
2、加“*”题目必做,其他题目任选;多选者并且保质保量完成适当加分。
3、严格按照数据结构实验报告模板和规范,及时完成实验报告。
四、实验步骤(说明:依据实验内容分别说明实验程序中用到的数据类型的定义、主程序的流程以及每个操作(成员函数)的伪码算法、函数实现、程序编码、调试与分析、总结、附流程图与主要代码)㈠、数据结构与核心算法的设计描述(程序中每个模块或函数应加注释,说明函数功能、入口及出口参数)1、单链表的结点类型定义/* 定义DataType为int类型 */typedef int DataType;/* 单链表的结点类型 */typedef struct LNode{ DataType data;struct LNode *next;}LNode,*LinkedList;2、初始化单链表LinkedList LinkedListInit( ){ // 每个模块或函数应加注释,说明函数功能、入口及出口参数 }3、清空单链表void LinkedListClear(LinkedList L){// 每个模块或函数应加注释,说明函数功能、入口及出口参数}4、检查单链表是否为空int LinkedListEmpty(LinkedList L){ …. }5、遍历单链表void LinkedListTraverse(LinkedList L){….}6、求单链表的长度int LinkedListLength(LinkedList L){ …. }7、从单链表表中查找元素LinkedList LinkedListGet(LinkedList L,int i){ //L是带头结点的链表的头指针,返回第 i 个元素 }8、从单链表表中查找与给定元素值相同的元素在链表中的位置LinkedList LinkedListLocate(LinkedList L, DataType x){ …… }9、向单链表中插入元素void LinkedListInsert(LinkedList L,int i,DataType x) { // L 为带头结点的单链表的头指针,本算法// 在链表中第i 个结点之前插入新的元素 x}10、从单链表中删除元素void LinkedListDel(LinkedList L,DataType x){ // 删除以 L 为头指针的单链表中第 i 个结点 }11、用尾插法建立单链表LinkedList LinkedListCreat( ){ …… }㈡、函数调用及主函数设计(可用函数的调用关系图说明)㈢程序调试及运行结果分析㈣实验总结五、主要算法流程图及程序清单1、主要算法流程图:2、程序清单(程序过长,可附主要部分)说明:以后每次实验报告均按此格式书写。
贵州大学数据结构实验任务指导书(实验报告版)综述
贵州大学计算机科学与技术学院计算机科学与技术系上机实验报告
贵州大学计算机科学与技术学院计算机科学与技术系上机实验报告
贵州大学计算机科学与技术学院计算机科学与技术系上机实验报告
贵州大学计算机科学与技术学院计算机科学与技术系上机实验报告
贵州大学计算机科学与技术学院计算机科学与技术系上机实验报告
贵州大学计算机科学与技术学院计算机科学与技术系上机实验报告
贵州大学计算机科学与技术学院计算机科学与技术系上机实验报告。
数据结构实验一 线性表的应用(班级通讯录代码及测试界面)
printf("\t**********************欢迎使用班级通讯录**********************\n\n"); printf("\t\t\t╔━━━━━═操作目录═━━━━━╗\n"); printf("\t\t\t┃ ┃\n"); printf("\t\t\t┃ ◇1.显示通讯录记录 ┃\n"); printf("\t\t\t┃ ┃\n"); printf("\t\t\t┃ ◇2.添加通讯录成员 ┃\n"); printf("\t\t\t┃ ┃\n"); printf("\t\t\t┃ ◇3.删除通讯录成员 ┃\n"); printf("\t\t\t┃ ┃\n"); printf("\t\t\t┃ ◇4.查找通讯录成员 ┃\n"); printf("\t\t\t┃ ┃\n"); printf("\t\t\t┃ ◇5.插入通讯录记录 ┃\n"); printf("\t\t\t┃ ┃\n"); printf("\t\t\t┃ ◇6.退出班级通讯录 ┃\n"); printf("\t\t\t┃ ┃\n"); printf("\t\t\t╚━━━━━━━━━━━━━━━━╝\n"); printf("\n\t**************************************************************\n"); printf("\n\n\t\t\t 请选择操作:"); scanf("%d",&set); printf("\n"); return set; } void key () { //任意键函数 printf("\n\t\t\t\t[按任意键返回主界面]\n\n"); getchar(); getchar(); }
实验一线性表操作实验报告
实验一_线性表操作_实验报告实验一:线性表操作一、实验目的1.理解线性表的基本概念和特点。
2.掌握线性表的基本操作,包括插入、删除、查找等。
3.通过实验,提高动手能力和解决问题的能力。
二、实验原理线性表是一种较为常见的数据结构,它包含零个或多个数据元素,相邻元素之间有前后关系。
线性表具有以下特点:1.元素之间一对一的顺序关系。
2.除第一个元素外,每个元素都有一个直接前驱。
3.除最后一个元素外,每个元素都有一个直接后继。
常见的线性表有数组、链表等。
本实验主要针对链表进行操作。
三、实验步骤1.创建链表:首先创建一个链表,并给链表添加若干个节点。
节点包括数据域和指针域,数据域存储数据,指针域指向下一个节点。
2.插入节点:在链表中插入一个新的节点,可以选择在链表的头部、尾部或中间插入。
3.删除节点:删除链表中的一个指定节点。
4.查找节点:在链表中查找一个指定数据的节点,并返回该节点的位置。
5.遍历链表:从头节点开始,依次访问每个节点的数据。
四、实验结果与分析1.创建链表结果:我们成功地创建了一个链表,每个节点都有数据域和指针域,数据域存储数据,指针域指向下一个节点。
2.插入节点结果:我们成功地在链表的头部、尾部和中间插入了新的节点。
插入操作的时间复杂度为O(1),因为我们只需要修改指针域即可。
3.删除节点结果:我们成功地删除了链表中的一个指定节点。
删除操作的时间复杂度为O(n),因为我们可能需要遍历整个链表才能找到要删除的节点。
4.查找节点结果:我们成功地在链表中查找了一个指定数据的节点,并返回了该节点的位置。
查找操作的时间复杂度为O(n),因为我们可能需要遍历整个链表才能找到要查找的节点。
5.遍历链表结果:我们成功地遍历了整个链表,并访问了每个节点的数据。
遍历操作的时间复杂度为O(n),因为我们可能需要遍历整个链表。
通过本次实验,我们更加深入地理解了线性表的基本概念和特点,掌握了线性表的基本操作,包括插入、删除、查找等。
一线性表实现与应用
实验一线性表实现与应用一、实验目的1.掌握线性表的顺序存储和链接存储结构。
2.了解线性表的应用。
3.分析顺序线性表与链接线性表的差异。
二、实验内容1.利用顺序线性表实现集合运算AUB。
2.利用向前链表实现集合运算(A-B)U(B-A)。
三、实验程序说明1.假设集合A和B的元素都是整数,并利用两个线性表la和lb分别存放集合A和B的成员。
现依次取出lb中的每个元素,按其值查找线性表la,若la中不存在该元素,则将它插入到la中去,最后线性表la就存放了集合AUB的元素。
2.(A-B)U(B-A)是由属于集合A或集合B,但又不同时属于A和B的全部元素组成。
我们可以先分别建立由集合A和集合B的元素构成的链表la和lb,然后对lb中每一个元素进行如下处理:在链表la中查找是否有相同元素,若有相同元素,则从la 中删除该元素;若没有相同元素,则将此元素插入la中。
最后,链表la就存放了(A-B)U(B-A)的全部元素。
四、参考程序1./* 求集合运算AUB */#define MAX 100typedef struct{char element[MAX];int num;} LIST;void create(LIST *list){int i,n;printf("Enter the number of list:");scanf("%d",&n);for(i=0;i<n;i++){printf("Enter element[%d]:",i+1);scanf("%d",&(list->element[i]));}list->num=n;}int insert(LIST *list, int m, int x){int i,n;n=list->num;if(n >= MAX){printf("The list is overflow! \n");return(-1);}else if(m < 1 || m > n+1){printf("Error! \n");return(-2);}else{for(i=n-1; i>=m-1; i--)list->element[i+1]=list->element[i];list->element[m-1]=x;list->num=n+1;return(0);}}int locate(LIST *list, int x){int i;for(i=0; i<=list->num-1; i++)if(list->element[i] == x)return(i+1);return(0);}void print_list(LIST *list){int i,n;n=list->num;if(n == 0)printf("The list is empty.\n");else{for(i=0; i<=n-1; i++)printf("%d\t",list->element[i]);printf("\n");}}main(){LIST *la,*lb;int i,x;create(la);printf("SET A:\n");print_list(la);create(lb);printf("SET B:\n");print_list(lb);for(i=0;i<lb->num;i++){x=lb->element[i];if(locate(la,x) == 0)insert(la,la->num+1,x);}printf("SET (AUB):\n");print_list(la);}2./* 集合运算(A-B)U(B-A)*/#include <stdio.h>typedef struct node{char info;struct node *link;} NODE;NODE *initial(),*process();main(){NODE *la,*lb,*ptr,*p1,*p2;printf("\nEnter the elements of Set A:");la=initial();printf("Set A:\n");travel(la);printf("\nEnter the elements of Set B:");lb=initial();printf("Set B:\n");travel(lb);la=process(la,lb);printf("\nSet (A-B)U(B-A):\n");travel(la);}NODE *initial(){NODE *head,*p1,*p2;char ch;head=(NODE *)malloc(sizeof(NODE));head->link=NULL;p1=head;while((ch=getchar()) != '\n'){p2=(NODE *)malloc(sizeof(NODE));p2->info=ch;p2->link=NULL;p1->link=p2;p1=p2;}return(head);}travel(NODE *ptr){ptr=ptr->link;while(ptr != NULL){printf("%c ",ptr->info);ptr=ptr->link;}printf("\n");}NODE *process(NODE *la,NODE *lb){NODE *ptr,*p1,*p2;int found=0;ptr=lb->link;while(ptr != NULL){p1=la->link;p2=la;while(p1 != NULL && ! found)if(p1->info == ptr->info)found=1;else{p2=p1;p1=p1->link;}if(found){p2->link=p1->link;free(p1);found=0;}else{p1=(NODE *)malloc(sizeof(NODE)); p1->info=ptr->info;p1->link=NULL;p2->link=p1;}ptr=ptr->link;}return(la);}/* 集合运算(A-B)U(B-A)*/#include <stdio.h>typedef struct node{char info;struct node *link;} NODE;NODE *initial(),*process();main(){NODE *la,*lb,*ptr,*p1,*p2;printf("\nEnter the elements of Set A:");la=initial();printf("Set A:\n");travel(la);printf("\nEnter the elements of Set B:");lb=initial();printf("Set B:\n");travel(lb);la=process(la,lb);printf("\nSet (A-B)U(B-A):\n");travel(la);}NODE *initial(){NODE *head,*p1,*p2;char ch;head=(NODE *)malloc(sizeof(NODE));head->link=NULL;p1=head;while((ch=getchar()) != '\n'){p2=(NODE *)malloc(sizeof(NODE));p2->info=ch;p2->link=NULL;p1->link=p2;p1=p2;}return(head);}travel(NODE *ptr){ptr=ptr->link;while(ptr != NULL){printf("%c ",ptr->info);ptr=ptr->link;}printf("\n");}NODE *process(NODE *la,NODE *lb){NODE *ptr,*p1,*p2;int found=0;ptr=lb->link;while(ptr != NULL){p1=la->link;p2=la;while(p1 != NULL && ! found)if(p1->info == ptr->info)found=1;else{p2=p1;p1=p1->link;}if(found){p2->link=p1->link;free(p1);found=0;}else{p1=(NODE *)malloc(sizeof(NODE));p1->info=ptr->info;p1->link=NULL;p2->link=p1;}ptr=ptr->link;}return(la);}五、实验步骤1.参考实验程序上机调试。
数据结构 实验1 线性表应用
void Init_SeqList(SeqList &L);//创建空顺序表算法 void Show_SeqList(SeqList L);//顺序表输出算法 void Create_SeqList(SeqList &L);//顺序表的创建算法 int Insert_SeqList(SeqList &L,DataType x,int i);//顺序表的插入算法 int Delete_SeqList(SeqList &L,int i);//顺序表的删除算法 void Sort_SeqList(SeqList &L);//顺序表的排序算法 int Insert_SeqList_sort(SeqList &L,DataType x);//有序表的插入算法 void menu(); //菜单算法
cin>>i; cout<<endl<<"请输入插入元素值:"; cin>>x;
cout<<endl; m=Insert_SeqList(L,x,i); if (m==1)
{ cout<<"插入操作后:"<<endl;
Show_SeqList(L); } else if (m==0) cout<<"插入位置不合法!"<<endl; else cout<<"发生溢出!"<<endl; break; }
int main() { menu(); }
void menu()
{
SeqList L;
Init_SeqList(L);
int m;
数据结构实验-线性表及其应用
实验1 线性表及其应用实验性质:验证性实验学时:2学时一、实验目的1.掌握线性表的顺序存储结构在计算机的表示方法及其基本操作的实现;2.掌握线性表的链式存储结构在计算机的表示方法及其基本操作的实现;3.能够利用线性表结构对实际问题进行分析建模,利用计算机求解。
二、实验预备知识1.复习C/C++语言相关知识(如:结构体的定义、typedef的使用、函数的定义、调用及参数传递方式);2.阅读并掌握顺序表与链表的类型定义及其查找、插入、删除等基本操作。
三、实验内容1.理解并分别用顺序表、链表的操作运行下列程序:#include <iostream>using namespace std;#include "Status.h"typedef int ElemType;#include "SqList.h" //用#include "LinkList.h"替换void main(){SqList L; //用LinkList L;替换,与#include "LinkList.h"配合int n,i;ElemType e;InitList(L);cout<<"\nL=";ListTraverse(L);cout<<"\n请设置将向线性表L中输入的元素个数:";cin>>n;CreateList(L,n);cout<<"\nL=";ListTraverse(L);cout<<"\nL的表长为:"<<ListLength(L)<<endl;cout<<"\n请输入想要获取的元素位序:";cin>>i;if(GetElem(L,i,e)) cout<<"\n第"<<i<<"个元素为:"<<e<<endl;else cout<<"\n第"<<i<<"个元素不存在!"<<endl;cout<<"\n请输入要查找的元素:";cin>>e;if(i=LocateElem(L,e)) cout<<"\n元素"<<e<<"的位置为:"<<i<<endl;else cout<<"\n元素"<<e<<"不存在!"<<endl;cout<<"\n请输入插入位置和所插入元素:";cin>>i>>e;if(ListInsert(L,i,e)){cout<<"\nL=";ListTraverse(L);}else cout<<"\n插入操作失败!"<<endl;cout<<"\n请输入被删元素的位置:";cin>>i;if(ListDelete(L,i,e)) cout<<"\n被删元素为:"<<e<<endl;else cout<<"\n删除操作失败!"<<endl;cout<<"\nL=";ListTraverse(L);}本题目说明:(1)头文件Status.h的内容如下:#define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define INFEASIBLE -1#define OVERFLOW -2typedef int Status;(2)头文件SqList.h(内容包括顺序表的结构定义及基本操作实现)。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验一线性表及应用一、实验目的1.复习C语言的上机环境,掌握C语言的基本结构;2.会定义线性表的顺序存储结构和链表的存储结构;3.熟悉对顺序表的一些基本操作和具体的函数定义。
4.掌握顺序表和单链表的存储结构及相关运算5.掌握顺序表和单链表的基本应用二、实验硬软件环境硬件环境:赛扬433以上CPU,10GB以上硬盘,64MB以上内存软件环境:DOS+Turbo C 2.0 或Borland C++ 3.1以上Windowx 9X+VC++ 5.0以上三、实验要求1.认真阅读和掌握本实验内容所给的全部程序。
2.保存和打印出程序运行结果,并结合程序进行分析。
3.按照你对顺序表操作的需要,屏幕考贝运行结果到实验报告中。
4.撰写实验报告并准时上交四、注意事项在做第一次“数据结构”课程实验之前,要在硬盘上建立好自己的工作目录,专门用来存储你所做的实验程序及相关信息,以后每次做实验都采用这个目录。
本实验设计完全由老师设计,版权限本班同学使用,勿外传。
实验材料下载到本机后,请用winrar软件释放到你的电脑磁盘的“数据结构实验(张三)”文件夹中,形成如上图的文件夹结构。
上交实验报告时,请把“实验一”的所有内容(含实验报告)用winrar打包成.rar文件后一并交上来。
上传名字为“实验一(张三).rar”五、基本理论线性表:线性表(linear list)是这样的数据对象,其实例形式为: (e1 , e2 ,... en ),其中n 是有穷自然数。
e是表中的元素,n 是表的长度。
元素i可以被视为原子,因为它们本身的结构与线性表的结构无关。
当n = 0 时,表为空;当n > 0时,e1是第一个元素,e n是最后一个元素,可以认为e l优先于e2,e优先于e3,如此等等。
除了这种优先关系之外,在线性表中不再有其他的结构。
2基本操作:• 创建一个线性表。
• 确定线性表是否为空。
• 确定线性表的长度。
• 查找第k个元素。
• 查找指定的元素。
• 删除第k个元素。
• 在第k个元素之后/之前插入一个新元素。
线性表ADT(图1):图1 线性表抽象数据类型顺序表:采用数组来表示一个对象的实例,数组中的每个位置被称之为单元(cell)或节点(node),每个数组单元应该足够大,以便能够容纳数据对象实例中的任意一个元素。
在某些情况下,每个实例可分别用一个独立的数组来描述,而在其他情况下,可能要使用一个数组来描述几个实例。
实例中每个元素在数组中的位置可以用一个数学公式来指明。
假定使用一个数组来描述表,需要把表中的每个元素映射到数组的具体位置上。
第一个元素在什么地方?第二个元素在什么地方?在公式化描述中,可用一个数学公式来确定每个元素的位置。
一个简单的映射公式如下:location(i)= i - 1 (式1-1)式1-1表明第i个元素的存储位置在数组的第i-1个位置;如果每个元素的长度为m,则可以通过公式计算第i个元素的存储地址:Address(i)=Address(1)+(i-1)*m (式1-2)Address(1)为第1个元素的址,即数组的首地址。
特别要记住的是第1个元素保存在数组的第0个位置。
图2 表性表实例简而言之,顺序表就是把线性表的元素存储在数组中,元素之间的关系直接通过相邻元素的位置来表达。
优点:简单,数据元素的提取速度快;缺点:(1)静态存储,无法预知问题规模的大小,可能空间不足,或浪费存储空间;(2)插入元素和删除元素时间复杂度高——O(n)链表:在存储线性表List中的每个元素e i时,同时存储元素的下一个元素的首地址(指针)Address(i+1),通过这种方法建立起元素之间的关系,从“逻辑”上看所有元素构成了图3所示的“链”,所以称为链表。
图3 一个单链表从图3可以看出元素之间的链接关系,为了“访问”每个元素e i的,必须知道e i的首地址,而这个首地址存储在其“直接前驱”结点e i-1中,……,按此规律,可以回推到元素e1的首地址。
即要访问List中任一元素e i,都必须从第一个元素e1开始,所以,必须保存首元素e1的地址在一个变量中(first),有的书使用Head作为变量名。
图3的单链表的首元素的地址在first中,我们可以直接用“first”称呼此单链表。
List中所有元素可以占用连续的存储空间,也可以占用不连续的存储空间。
但是从“逻辑”上来看所有元素仍然满足“一对一”的关系,即:(1)首元素没有“直接前驱”,尾元素没有“直接后继”。
(2)中间元素有且仅有一个“直接前驱”和“直接后继”为了实现这种存储结构,可以使用C语言作如下定义:的一个结点类型(用以存储一个数据元素,这样可以定义一个结点变量存储一个数据元素:LinkNode a;也可定义一个“结点”指针保存某个结点的首地址:LinkNode *p;对于其它可能不支持动态存储分配的高级语言来说,上述LinkNode类型定义时就内部就不能使用地址,但是我们可以利用数组“模拟”链表的功能,这种链中的“位置”,这样定义的链表如图4所示:图4 静态链表链表还有“循环链表”(图5)和“双链表”(图6),无论多么复杂的链表,其基础都是单链表,因此,完全掌握单链表后,学习其它有关链接存储将会变得简单得多,这是本章我们的重点任务。
循环单链表,实际上是利用链表的“尾结点”的空指针来指向链表的首结点。
有循环链表后,只要知道链表中任一结点的地址,就可以访问链表中所所有结点。
注意图5b引入了一“头结点”,目的是让空链表与非空链表统一,方便操作实现。
图5 循环单链表双链表是在单链表的基础上,在数据元素中再增加一个冗余项,用以保存结点的“直接前驱”结点的地址,这样结点既可以指向“直接后继”,也可以指向“直接前驱”,实现链表的双向查找。
图6 双向链表链表最大的优点是在某个元素之后插入结点或删除结点非常方便,时间复杂度为常数O(1)。
缺点是空间利用率低,存取指定元素效率低O(n)。
六、实验内容与过程本实验用到的文件有(在文件夹“实验一\实验材料\”中)Lineast.h、Lineast.cpp、LineastTest.cpp 、Link.h、Link.cpp、、LinkTest.cpp 前三个文件保存在子目录“SqList”中,后三个保存在子目录“Link”中后缀有“Test”的文件用以测试顺序表和链表的各项操作的正确性,里面包含了主函数“main”。
*.h文件中包含了数据结构的定义,对应的同名cpp文件包含了对数据结构进行的各种操作的实现。
请按以下提示完成所有实验。
(一)文件Lineast.cpp是顺序表的实现,其中有三个函数没有完全实现,请同学认真阅读整个程序,然后根据所学的知识完善,完善后编译Lineast.cpp,然for(int j=L->Length+1;j>i;j--){L->data[j]=L->data[j-1];}L->Length++;{printf("error");return 0;}elsefor(j=i;j<L->Length;j++) {L->data[j]=L->data[j+1];}L->Length--;for(int m=1;m<=n;m++) {if(L->data[m]==*e){j=m;break;}elsecontinue;}图7 运行菜单对菜单中的每个功能项进行测试,以了解程序是否按照要求完成指定工作。
屏显:)输入3,回车后,根据屏幕提示输入1,回车屏显:)输入3,回车后,根据屏幕提示输入3,回车屏显:)输入3,回车后,根据屏幕提示输入7,回车屏显:屏显:)输入3,回车后,根据屏幕提示输入:0,回车屏显:原因:此表是从1开始的,不存在0号元素输入3,回车后,根据屏幕提示输入小于等于0的数,回车屏显:原因:此表是从1开始的,不存在-1号元素)输入4,回车后,根据屏幕提示输入:35 3,回车屏显:)输入4,回车后,根据屏幕提示输入:10 1,回车屏显:)输入4,回车后,根据屏幕提示输入:5 0,回车屏显:原因:插入元素必须为在1到L->length+1之间)输入4,回车后,根据屏幕提示输入:5 -1,回车屏显:原因:插入元素必须为在1到L->length+1之间)输入4,回车后,根据屏幕提示输入:90 9,回车屏显:)输入4,回车后,根据屏幕提示输入:95 10,回车屏显:)输入4,回车后,根据屏幕提示输入:100 12,回车屏显:原因:插入元素必须为在1到L->length+1之间)输入5,回车屏显:)输入6,回车后,根据屏幕提入示输入:70 4,回车屏显:)输入6,回车后,根据屏幕提入示输入:5 0,回车屏显:原因:对表操作必须在1到L->length)输入6,回车后,根据屏幕提入示输入:100 9,回车屏显:)输入6,回车后,根据屏幕提入示输入:110 11,回车屏显:修改元素后并为对L->length进行++)输入7,回车后,根据屏幕提入示输入:6,回车屏显:)输入7,回车后,根据屏幕提入示输入:0,回车屏显:数组是从1开始的)输入7,回车后,根据屏幕提入示输入:10,回车屏显:原因:第10号元素存在,并且为95)输入8,回车屏显:)输入2,回车屏显:原因:L->length被清0进一步思考并回答:(1)步骤1、2分别用来干什么?答:初始化一个顺序表(2)步骤2-8用来干什么?其中步骤5-8有什么用?答:2到8是用来删除一个元素,5到8是用来验证当删除条件不满足时是否能执行删除。
(3)步骤9-14用来干什么?其中11、12、13、14的目的是什么?答:9到14是用来加入一个元素,11到14是用来验证当插入条件不满足时是否能进行插入。
(4)步骤16-19作用是什么?答:是用来改变一个表内元素的值。
(5)步骤20-21作用是什么?答:是用来验证当改变条件不满足时,是否能改变一个表内元素的值。
(二)单链表的操作实现放在Link.CPP中,其中有几个函数未完成(如下),请int n=GetLength(L);if(i<1||i>n)return NULL;if(i==1)return p;for(j=0;j<=n;j++){if(j!=i-1)p=p->next;else break;}{s->next=*L;*L=s;return 1;}if(p==NULL){printf("error");return 0;}else{s->next=p->next;p->next=s;if(i==1){q=*L;*L=(*L)->next;return 1;}if(p==NULL||p->next==NULL){printf("invaild position to delete!\n");return 0;}else{q=p->next;p->next=q->next;free(q);图8 链表操作菜单屏幕出现图8菜单后,请按(一)中的数据和操作步骤(1)-(24)测试所有屏显:)输入3,回车后,根据屏幕提示输入1,回车屏显:)输入3,回车后,根据屏幕提示输入3,回车屏显:)输入3,回车后,根据屏幕提示输入7,回车屏显:屏显:)输入3,回车后,根据屏幕提示输入:0,回车屏显:原因:因为链表是从1开始的,不存在0号元素输入3,回车后,根据屏幕提示输入小于等于0的数,回车屏显:原因:此表是从1开始的,不存在-1号元素)输入4,回车后,根据屏幕提示输入:35 3,回车屏显:)输入4,回车后,根据屏幕提示输入:10 1,回车屏显:)输入4,回车后,根据屏幕提示输入:5 0,回车屏显:原因:链表是从1开始的,不存在0号位置)输入4,回车后,根据屏幕提示输入:5 -1,回车屏显:原因:插入元素必须为在1到链表的长度+1之间)输入4,回车后,根据屏幕提示输入:90 9,回车屏显:)输入4,回车后,根据屏幕提示输入:95 10,回车屏显:)输入4,回车后,根据屏幕提示输入:100 12,回车屏显:原因:插入元素必须为在1到链表的长度+1之间屏显:)输入6,回车后,根据屏幕提入示输入:70 4,回车屏显:)输入6,回车后,根据屏幕提入示输入:5 0,回车屏显:原因:对表操作必须在1到链表的长度之间)输入6,回车后,根据屏幕提入示输入:100 9,回车屏显:)输入6,回车后,根据屏幕提入示输入:110 11,回车屏显:修改元素必须在1到链表长度之间屏显:)输入7,回车后,根据屏幕提入示输入:0,回车屏显:查找元素必须在1到链表长度之间)输入7,回车后,根据屏幕提入示输入:10,回车屏显:原因:该链表的第10项为95)输入8,回车屏显:)输入2,回车屏显:原因:L中的结点被释放,且L指向空比对(一)与(二)的运行结果,你发现了什么?你认为这说明了什么问题?答:运行结果相似,说明顺序表和链表都可以实现相同功能。