数据结构实验一题目一线性表实验报告

合集下载

1数据结构-实验报告一(线性表的基本操作)

1数据结构-实验报告一(线性表的基本操作)

实验一 线性表的基本操作及其应用一、实验目的1、帮助读者复习C++语言程序设计中的知识。

2、熟悉线性表的逻辑结构。

3、熟悉线性表的基本运算在两种存储结构上的实现。

4、掌握顺序表的存储结构形式及其描述和基本运算的实现。

5、熟练掌握动态链表结构及有关算法的设计二、实验内容求两个多项式的相加运算[问题描述]用单链表存储一元多项式,并实现两个多项式的相加运算。

[基本要求](1)本程序需要基于线性表的基本操作来实现一元多项式的加法,也可以用数组实现。

;(2)两个多项式都有键盘输入相应的系数和指数[测试数据] 由学生任意指定。

三、源代码#include <stdio.h>#include <malloc.h>#define MAX 20 //多项式最多项数typedef struct //定义存放多项式的数组类型{double coef; //系数int exp; //指数} PolyArray[MAX];typedef struct pnode //定义单链表结点类型{double coef; //系数int exp; //指数struct pnode *next;} PolyNode;void DispPoly(PolyNode *L) //输出多项式{bool first=true; //first为true表示是第一项PolyNode *p=L->next;while (p!=NULL){if (first)first=false;else if (p->coef>0)printf("+");if (p->exp==0)printf("%g",p->coef);else if (p->exp==1)printf("%gx",p->coef);elseprintf("%gx^%d",p->coef,p->exp);p=p->next;}printf("\n");}void DestroyList(PolyNode *&L) //销毁单链表{PolyNode *p=L,*q=p->next;while (q!=NULL){free(p);p=q;q=p->next;}free(p);}void CreateListR(PolyNode *&L,PolyArray a,int n) //尾插法建表{PolyNode *s,*r;int i;L=(PolyNode *)malloc(sizeof(PolyNode)); //创建头结点L->next=NULL;r=L; //r始终指向终端结点,开始时指向头结点for (i=0;i<n;i++){s=(PolyNode *)malloc(sizeof(PolyNode));//创建新结点s->coef=a[i].coef;s->exp=a[i].exp;r->next=s; //将*s插入*r之后r=s;}r->next=NULL; //终端结点next域置为NULL}void Sort(PolyNode *&head) //按exp域递减排序{PolyNode *p=head->next,*q,*r;if (p!=NULL) //若原单链表中有一个或以上的数据结点{r=p->next; //r保存*p结点后继结点的指针 p->next=NULL; //构造只含一个数据结点的有序表 p=r;while (p!=NULL){r=p->next; //r保存*p结点后继结点的指针 q=head;while (q->next!=NULL && q->next->exp>p->exp)q=q->next; //在有序表中找插入*p的前驱结点*qp->next=q->next; //将*p插入到*q之后q->next=p;p=r;}}}void Add(PolyNode *ha,PolyNode *hb,PolyNode *&hc) //求两有序集合的并{PolyNode *pa=ha->next,*pb=hb->next,*s,*tc;double c;hc=(PolyNode *)malloc(sizeof(PolyNode)); //创建头结点tc=hc;while (pa!=NULL && pb!=NULL){if (pa->exp>pb->exp){s=(PolyNode *)malloc(sizeof(PolyNode)); //复制结点s->exp=pa->exp;s->coef=pa->coef;tc->next=s;tc=s;pa=pa->next;}else if (pa->exp<pb->exp){s=(PolyNode *)malloc(sizeof(PolyNode)); //复制结点s->exp=pb->exp;s->coef=pb->coef;tc->next=s;tc=s;pb=pb->next;}else //pa->exp=pb->exp{c=pa->coef+pb->coef;if (c!=0) //系数之和不为0时创建新结点{s=(PolyNode *)malloc(sizeof(PolyNode)); //复制结点s->exp=pa->exp;s->coef=c;tc->next=s;tc=s;}pa=pa->next;pb=pb->next;}}if (pb!=NULL) pa=pb; //复制余下的结点while (pa!=NULL){s=(PolyNode *)malloc(sizeof(PolyNode)); //复制结点 s->exp=pa->exp;s->coef=pa->coef;tc->next=s;tc=s;pa=pa->next;}tc->next=NULL;}void main(){PolyNode *ha,*hb,*hc;PolyArray a={{2.3,0},{-2.8,2},{5.6,3},{-10.9,7},{7.6,10}};PolyArray b={{-1.2,0},{8.6,1},{-13.9,3},{15.5,5},{5.6,9}};CreateListR(ha,a,5);CreateListR(hb,b,5);printf("原多项式A: ");DispPoly(ha);printf("原多项式B: ");DispPoly(hb);Sort(ha);Sort(hb);printf("有序多项式A: ");DispPoly(ha);printf("有序多项式B: ");DispPoly(hb);Add(ha,hb,hc);printf("多项式相加: ");DispPoly(hc);DestroyList(ha);DestroyList(hb);DestroyList(hc);}四、测试结果五、心得体会两个简单的的多项式用相加,编程却需要线性表各种用法显得很复杂。

数据结构线性表实验报告

数据结构线性表实验报告

实验报告实验一线性表实验目的:1. 理解线性表的逻辑结构特性;2. 熟练掌握线性表的顺序存储结构的描述方法,以及在该存储结构下的基本操作;并能灵活运用;3. 熟练掌握线性表的链表存储结构的描述方法,以及在该存储结构下的基本操作;并能灵活运用;4•掌握双向链表和循环链表的的描述方法,以及在该存储结构下的基本操作。

实验原理:线性表顺序存储结构下的基本算法;线性表链式存储结构下的基本算法;实验内容:2 - 21设计单循环链表,要求:(1 ) 单循环链表抽象数据类型包括初始化操作、求数据元素个数操作、插入操作、删除操作、取消数据元素操作和判非空操作。

(2 ) 设计一个测试主函数,实际运行验证所设计单循环链表的正确性。

2 — 22 .设计一个有序顺序表,要求:(1 ) 有序顺序表的操作集合有如下操作:初始化、求数据元素个数、插入、删除和取数据元素。

有序顺序表与顺序表的主要区别是:有序顺序表中的数据元素按数据元素值非递减有序。

(2 ) 设计一个测试主函数,实际运行验证所设计有序顺序表的正确性。

(3) 设计合并函数ListMerge ( L1,L2,L3 ),功能是把有序顺序表 L1和L2中的数据元素合并到L3,要求L3中的数据元素依然保持有序。

并设计一个主函数,验证该合并函数的正确性。

程序代码:2-21 (1)头文件 LinList.h 如下:typedef struct node{DataType data;struct node *next;}SLNode;/* ( 1 )初始化 ListInitiate(SLNode * * head)*/void ListInitiate(SLNode * * head){ /* 如果有内存空间,申请头结点空间并使头指针 head 指向头结点 */if((*head=(SLNode *)malloc(sizeof(SLNode)))==NULL)exit(1);(*head)->next=NULL; /* 置结束标记 NULL*/}/*(2) 求当前数据元素个数 ListLength(SLNode * head)*/int ListLength(SLNode * head){SLNode *p=head;int size=0;while(p->next!=head){p=p->next;size++;}return size;}/*(3) 插入 ListInsert(SLNode * head , int i , DataType x)*//* 在带头结点的单链表的第 i(0<=i<=size) 个结点前 *//* 插入一个存放数据元素 x 的结点。

数据结构实验报告-线性表(顺序表实现)

数据结构实验报告-线性表(顺序表实现)

实验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.归并顺序表(销毁或清空操作前)七、思考讨论题或体会或对改进实验的建议通过本次实验,我掌握了定义线性表的顺序存储类型,加深了对顺序存储结构的理解,进一步巩固和理解了顺序表的基本操作,如建立、查找、插入和删除等。

数据结构线性表试验报告(最终定稿)

数据结构线性表试验报告(最终定稿)

数据结构线性表试验报告(最终定稿)第一篇:数据结构线性表试验报告线性表上机实习1、实验目的(1)熟悉将算法转换为程序代码的过程。

(2)了解顺序表的逻辑结构特性,熟练掌握顺序表存储结构的C 语言描述方法。

(3)熟练掌握顺序表的基本运算:查找、插入、删除等,掌握顺序表的随机存取特性。

(4)了解线性表的链式存储结构,熟练掌握线性表的链式存储结构的C语言描述方法。

(5)熟练掌握线性链表(单链表)的基本运算:查找、插入、删除等,能在实际应用中灵活选择适当的链表结构。

2、实验要求(1)熟悉顺序表的插入、删除和查找。

(2)熟悉单链表的插入、删除和查找。

3、实验内容: ① 顺序表(1)抽象数据类型定义typedef struct {TypeData data[maxsize];//容量为maxsize的静态顺手表int n;//顺序表中的实际元素个数}SeqList;//静态顺序表的定义在本次实验中,首先建立一个空的静态顺序表,然后键盘输入数据存入表中,然后进入菜单选择界面,通过不同的数字输入,实现对顺序表,删除,插入,查找,显示等操作。

(2)存储结构定义及算法思想在顺序表结构体的定义中,typedef int TypeData 为整型,存储结构如下:for(n=0;ncout<<“请输入线性表数据”<cin>>L.data[n];//顺序将数据存入顺序表}//其他存储与此类似,都是直接赋值与数组的某一位插入版块子函数:void insert(SeqList &L)//插入数据 {int a,b,c,k;cout<<“请输入插入的数及其插入的位置”<cin>>a>>b;if(b<=0||b>(L.n+1)){cout<<“不能在该位置插入”<k=L.data[b-1];L.data[b-1]=a;c=L.n;L.n=L.n+1;while(c>b){L.data[c]=L.data[c-1];c--;//通过循环,实现插入位置后的数据挨个往后移动一位}L.data[b]=k;} 顺序表的插入与删除操作类似,在插入与删除后,都要循环调整后面数组的每一位元素,同时记录数据元素的长度的标示符也要跟着改变。

《数据结构》实验1实验报告

《数据结构》实验1实验报告

南京工程学院实验报告<班级>_<学号>_<实验X>.RAR文件形式交付指导老师。

一、实验目的1.熟悉上机环境,进一步掌握语言的结构特点。

2.掌握线性表的顺序存储结构的定义及实现。

3.掌握线性表的链式存储结构——单链表的定义及实现。

4.掌握线性表在顺序存储结构即顺序表中的各种基本操作。

5.掌握线性表在链式存储结构——单链表中的各种基本操作。

二、实验内容1.顺序线性表的建立、插入及删除。

2.链式线性表的建立、插入及删除。

三、实验步骤1.建立含n个数据元素的顺序表并输出该表中各元素的值及顺序表的长度。

2.利用前面的实验先建立一个顺序表L={21,23,14,5,56,17,31},然后在第i个位置插入元素68。

3.建立一个带头结点的单链表,结点的值域为整型数据。

要求将用户输入的数据按尾插入法来建立相应单链表。

四、程序主要语句及作用程序1的主要代码(附简要注释)public struct sequenlist{public const int MAXSIZE=1024; /*最大值为1024*/public elemtype[] vec;public int len; /* 顺序表的长度 */public sequenlist( int n){vec=new elemtype[MAXSIZE ];len = n;}};class Program{static void Main(string[] args){sequenlist list1 = new sequenlist(5);for (int i = 0; i < 5; i++){list1.vec[i] = i;}for (int i = 0; i < 5; i++){Console.Write("{0}---", list1.vec[i]) ;}Console.WriteLine("\n");Console.WriteLine("表长:{0}\n",list1.len );Console.ReadKey();}}程序2的主要代码(附简要注释)public void insertlist(int i, int x){if (len >= MAXSIZE)throw new Exception("上溢"); /*长度大于最大值则抛出异常*/if (i < 1 || i > len + 1)throw new Exception("位置");/插入位置小于1或大于len+1则抛出插入位置错误的异常for (int j = len; j >= i; j--)vec[j] = vec[j - 1]; //注意第j个元素存在数组下标为j-1处vec[i - 1] = x;len++;}};class Program{static void Main(string[] args){sequenlist list2 = new sequenlist(7);list2.vec[0] = 21;list2.vec[1] = 23;list2.vec[2] = 14;list2.vec[3] = 5;list2.vec[4] = 56;list2.vec[5] = 17;list2.vec[6] = 31;Console.Write("请输入第i个位置插入元素:");int loc =Convert.ToInt32( Console.ReadLine());Console.Write("请输入第{0}个位置插入的元素:", loc);int ele = Convert.ToInt32(Console.ReadLine());Console.WriteLine("插入前的线性表:");for (int i = 0; i < list2.len ; i++){Console.Write("{0}---", list2.vec[i]);}Console.WriteLine("\n");list2.insertlist(loc, ele);Console.WriteLine("插入后的线性表:");for (int i = 0; i < list2.len ; i++){Console.Write("{0}---", list2.vec[i]);}Console.WriteLine("\n");Console.ReadKey();}}程序3的主要代码(附简要注释)class Node{private int num;public int Num{set { num = value; }/输入值get { return num; }/获得值}private Node next;public Node Next{set { next = value; }get { return next; }}}class Pp{static void Main(string[] args){Node head;Node tempNode, tempNode1;int i;head = new Node();Console.WriteLine("输入六项数据:\n");Console.Write("输入第1项数据:");head.Num = Convert.ToInt32(Console.ReadLine());head.Next = null;tempNode = head;for (i = 1; i < 6; i++){tempNode1 = new Node();Console.Write("输入第{0}项数据:",i+1);tempNode1.Num = Convert.ToInt32(Console.ReadLine());/插入项转换为整形数值 tempNode1.Next = null;tempNode.Next = tempNode1;tempNode = tempNode.Next;}Console.WriteLine("线性表:");tempNode = head;for (i = 0; i < 6; i++){Console.Write("{0}", tempNode.Num);if (i < 5){Console.Write("--");}tempNode = tempNode.Next;}Console.ReadKey();}}五、程序运行结果截图程序1程序2程序3六、收获,体会及问题(写得越详细、越个性化、越真实越好,否则我不知道你做这个实验的心路历程,也就无法充分地判断你是否是独立完成的这个实验、你是否在做这个实验时进行了认真仔细地思考、通过这个实验你是否在实践能力上得到了提高)这次试验刚开始做时完全不知道从哪下手,才刚上了几节课,对于线性表、链式表都不是理解的很透彻,不知道用哪个软件编写程序。

数据结构实验一-线性表

数据结构实验一-线性表

数据结构实验⼀-线性表实验⼀线性表⼀、实验⽬的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];/*将未完成的代码补全,提⽰:此处添加⼀条语句,将被删除元素之后的元素左移。

数据结构实验一线性表

数据结构实验一线性表

数据结构实验⼀线性表数据结构与算法实验报告实验⼀:线性表操作实验—⽤循环链表实现约瑟夫环问题姓名:沈靖雯学号:2014326601094班级:14信科⼆班⼆〇⼀六年⼗⽉实验⼀线性表操作实验【实验内容】实现线性表的初始化和插⼊删除操作提⾼部分实验:⽤循环链表实现约瑟夫环问题【实验⽬的】掌握线性表的顺序映象和链式映象⽅式,能熟练掌握链表结构的使⽤。

【问题描述】⼀个旅⾏社要从n 个旅客中选出⼀名旅客,为他提供免费的环球旅⾏服务。

旅⾏社安排这些旅客围成⼀个圆圈,从帽⼦中取出⼀张纸条,⽤上⾯写的正整数m(要求:⽤C 或C++语⾔实现,对某个给定的n 和m (例如n=7和m=3),给出被淘汰出列的旅客编号序列,以及最终的幸存者。

要求实验结果上机演⽰,最终以实验报告(附原程序)的⽅式递交。

【问题的实现】⼀、线性表初始化和插⼊删除操作(1)抽象数据类型ADT SqList {数据对象: 0}n n,,1,2,3,i ElemSet,a |{a i i≥?=∈=D数据关系: n},2,3,i D,a ,a |a ,a {1i 1-i i 1-i ?=∈=R 基本操作: InitList_Sq(&L)操作结果:构造⼀个空的线性表L 。

GetElem(L,i,&e)初始条件:线性表L 已存在,)(L L istLength i 1≤≤。

操作结果:⽤e 返回L 中第i 个元素的值。

ListInsert_Sq(&L,i,e)初始条件:线性表L 已存在,1istLengthi 1+≤≤)(L L 。

操作结果:在L 中第i 个位置之前插⼊新数据元素e ,L 长度加1。

ListDelete_Sq(&L,i,e)初始条件:循环链表L 已存在且⾮空,)(L L istLength i 1≤≤。

操作结果:删除L 第i 个数据元素,⽤e 返回其值,L 长度减1。

ListPrint_Sq (&L )初始条件:线性表L 已存在。

实验一 线性表 实验报告

实验一 线性表 实验报告

数据结构实验报告实验名称:实验一线性表学生姓名:班级:班内序号:学号:日期:2012年11月3日1、实验要求据线性表的抽象数据类型的定义,选择下面任一种链式结构实现线性表,并完成线性表的基本功能。

线性表存储结构(五选一):1、带头结点的单链表2、不带头结点的单链表3、循环链表4、双链表5、静态链表线性表的基本功能:1、构造:使用头插法、尾插法两种方法2、插入:要求建立的链表按照关键字从小到大有序3、删除4、查找5、获取链表长度6、销毁7、其他:可自行定义编写测试main()函数测试线性表的正确性2、程序分析2.1存储结构单链表的存储结构2.2关键算法分析一:关键算法1:头插法自然语言描述:a:在堆中建立新结点b:将a[i]写入到新结点的数据域c:修改新结点的指针域d:修改头结点的指针域,并将新结点加入链表中伪代码描述:a:Node * s=new Node ;b:s->data=a[i] ;c:s->next=front->next;d:front->next=s;2:尾插法自然语言描述:a:在堆中建立新结点b:将a[i]写入到新结点的数据域c:将新结点加入到链表中d:修改尾指针伪代码描述:a:Node * s=new Node ;b:s->data=a[i] ;c:r->next=s;d:r=s;3:删除大于min小于max元素算法:自然语言描述:a:建立新结点b:保存第一个结点的位置c:执行循环,查找到p结点为第一个大于min小于max的元素,q为比min 大的前一个元素位置d:执行循环,查找到比max小的最后一个元素位置e:将上述两步骤中的满足条件的中间节点删掉f:将前后两条断链重新连接起来,连接p和q结点伪代码描述:a:Node *p,*q,*r;b: p=front->next;c:while(p&&p->data<=min){q=p;p=p->next;}d和e:while(p&&p->data<max) //找比max小的最后一个元素位置{r=p;p=p->next;delete r; //释放满足条件的结点}f: q->next=p;4:链表逆置算法自然语言描述:a:建立新结点b:判断链表是否为空表或者单结点链表c:将开始结点变成终端结点d:执行循环,使每次循环都将后一个结点变成开始结点e:遍历打印伪代码描述:a:Node *p,*q;b:if(front->next&&front->next->next)c: p=front->next;q=p->next;p->next=NULL;d:while(q){p=q; //每次循环将后一个结点变成起始结点q=q->next;p->next=front->next;front->next=p;}e: z=front->next;while(z) //遍历打印逆置后的序列{cout<<z->data<<"";z=z->next;}5.销毁函数自然语言描述:a:新建立一个指针,指向头结点b:判断要释放的结点是否存在c:暂时保存要释放的结点d:移动a中建立的指针e:释放要释放的指针伪代码描述:a:Node * p=frontb:while(p)c:front=pd:p=p->nexte:delete front6.按位查找函数(查找第i个元素的位置)自然语言描述:a:初始化工作指针p和计数器j,p指向第一个结点,j=1b:循环以下操作,直到p为空或者j等于1b1:p指向下一个结点b2:j加1c:若p为空,说明第i个元素不存在,抛出异常d:否则,说明p指向的元素就是所查找的元素,返回元素地址伪代码描述a:Node * p=front->next;j=1;b:while(p&&(j!=i))b1:p=p->nextb2:j++c:if(!p) throw ”查找位置有误”d:return p7:按位查找函数(查找值为x的元素并返回其位置)自然语言描述:a:初始化工作指针p和计数器j,p指向第一个结点,j=1b:循环以下操作,找到这个元素或者p指向最后一个结点b1:判断p指向的结点是不是要查找的值,如果是,返回j,否则p指向下一个结点,并且j的值加1c:如果找到最后一个结点还没有找到要查找的元素,返回查找失败信息伪代码描述:a:Node * p=front->next;j=1;b:while(p)b1: if(p->next==x)return j;p=p->next;j++ ;c:throw "找不到指定元素";8.插入函数自然语言描述:a:在堆中建立新结点b:将要插入的结点的数据写入到新结点的数据域c:修改新结点的指针域d:修改前一个指针的指针域,使其指向新插入的结点的位置伪代码描述:a:Node * s=new Node ;b:s-data=xc:s->next=p->nextd:p->next=s9.删除函数自然语言描述:a:从第一个结点开始,查找要删除的位数i前一个位置i-1的结点b:设q指向第i个元素c:将q元素从链表中删除d:保存q元素的数据e:释放q元素伪代码描述:a: if(i!=1)p=Get(i-1);b: q=p->nextc:p->next=q->nextd:x=q->datae:delete q10.遍历输出函数自然语言描述:a:判断该链表是否为空链表,如果是,报错b:如果不是空链表,新建立一个temp指针c:将temp指针指向头结点d:打印temp指针的data域e:逐个往后移动temp指针,直到temp指针指向的next域为空伪代码描述:a:If(front->next==NULL)cout<<"该链表为空链表!"<<endl;b和c:Node * temp=front->next;d和e:while(temp){cout<<temp->data<<"";temp=temp->next;}11.获取链表长度函数自然语言描述:a:判断该链表是否为空链表,如果是,输出长度0b:如果不是空链表,新建立一个temp指针,初始化整形数n为0c:将temp指针指向头结点d:判断temp指针是否为空,如果不是,n加1,否则return ne: 使temp指针逐个后移,重复d操作,直到temp指针指向的next域为0,返回n伪代码描述:a:int n=0;if(front->next==NULL) //如果为空链表{n=0;}b和c: else{Node * temp=front->next;d:while(temp){n++;e: temp=temp->next;}}return n;二、代码详细分析1、头插法关键代码:Node * s=new Node ;s->data=a[i] ;s->next=front->next;front->next=s;示意图:2、尾插法关键代码:Node * s=new Node ;s->data=a[i] ;r->next=s;r=s;示意图:3:删除大于min 小于max 元素算法:关键代码:Node *p,*q,*r,*s;p=front->next;while (p&&p->data<=min){q=p;p=p->next;} //此循环结束时,当前p 结点为第一个大于min 小于max 的元素,q 为比min 大的前一个元素位置while (p&&p->data<max) //找比max 小的最后一个元素位置{r=p;p=p->next;delete r; //释放满足条件的结点}q->next=p;流程图:4:链表逆置算法关键代码:Node *p,*q,*z;if (front->next&&front->next->next) //当链表不是空表或者单结点时{p=front->next;q=p->next;p->next=NULL; //将开始结点变成终端结点while(q){p=q; //每次循环将后一个结点变成起始结点q=q->next;p->next=front->next;front->next=p;}}流程图:5、查找算法关键代码:Node *p=front->next;int j=1;while(p&&(j!=i)) //i=1时循环体不执行{p=p->next;j++;}if(!p) throw"查找位置有误";elsereturn p;流程图:六、删除算法关键代码:Node *p=front;if (i!=1)p=Get(i-1); //查到第i-1个元素的地址Node *q=p->next;p->next=q->next;int x=q->data;delete q;return x;流程图:三、关键算法的时间、空间复杂度头插法/尾插法 O(n)按位查找/按值查找 O(n)插入操作 O(n)逆置操作 O(n)删除大于min小于max操作o(n)2.3其他函数中的按值查找可以修改,把终止条件改为直到指向的结点的next域为空,返回多个地址,那么在链表中如果存在多个待找元素都可以返回。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

数据结构实验报告实验名称:实验1——线性表学生姓名:班级:班内序号:学号:日期:1.实验要求1、实验目的:熟悉C++语言的基本编程方法,掌握集成编译环境的调试方法学习指针、模板类、异常处理的使用掌握线性表的操作的实现方法学习使用线性表解决实际问题的能力2、实验内容:题目1:线性表的基本功能:1、构造:使用头插法、尾插法两种方法2、插入:要求建立的链表按照关键字从小到大有序3、删除4、查找5、获取链表长度6、销毁7、其他:可自行定义编写测试main()函数测试线性表的正确性。

2. 程序分析2.1 存储结构带头结点的单链表2.2 关键算法分析1.头插法a、伪代码实现:在堆中建立新结点将x写入到新结点的数据域修改新结点的指针域修改头结点的指针域,将新结点加入链表中b、代码实现:Linklist::Linklist(int a[],int n)//头插法{front=new Node;front->next=NULL;for(int i=n-1;i>=0;i--){Node*s=new Node;s->data=a[i];s->next=front->next;front->next=s;}}2、尾插法a、伪代码实现:a.在堆中建立新结点b.将a[i]写入到新结点的数据域c.将新结点加入到链表中d.修改修改尾指针b、代码实现:Linklist::Linklist(int a[],int n,int m)//尾插法{front=new Node;Node*r=front;for(int i=0;i<n;i++){Node*s=new Node;s->data=a[i];r->next=s;r=s;}r->next=NULL;}时间复杂度:O(n)3、按位查找a、伪代码实现: 初始化工作指针p和计数器j,p指向第一个结点,j=1循环以下操作,直到p为空或者j等于1b1:p指向下一个结点b2:j加1若p为空,说明第i个元素不存在,抛出异常否则,说明p指向的元素就是所查找的元素,返回元素地址b、代码实现Node* Linklist::Get(int i)//得到指向第i个数的指针{Node*p=front->next;int j=1;while(p&&j!=i)//p非空且j不等于i,指针后移{p=p->next;j++;}return p;}4、插入操作a、伪代码实现: 如果链表为空,直接插入判断p的下一个结点的值大于x且p的值小于x在堆中建立新结点将要插入的结点的数据写入到新结点的数据域修改新结点的指针域修改前一个指针的指针域,使其指向新插入的结点的位置b、代码实现void Linklist::Insert(int x)//将x按顺序插入{Node*p=front->next;if(!p)//如果链表为空,直接插入{Node*s=new Node;s->data=x;s->next=front->next;front->next=s;}elsewhile(!((p->next->data>x)&&(p->data<x)))//判断p的下一个结点的值大于x且p的值小于x{p=p->next;}Node*s=new Node;//将x插入到p之后s->data=x;s->next=p->next;p->next=s;}5、删除操作a、伪代码实现:从第一个结点开始,查找要删除的位数i前一个位置i-1的结点设q指向第i个元素将q元素从链表中删除保存q元素的数据释放q元素b、代码实现int Linklist::Delete(int i)//删除第i个位置的结点{Node*p=front;if(i!=1)p=Get(i-1);//得到第i-1个位置的指针Node*q=p->next;p->next=q->next;int x=q->data;delete q;return x;}6遍历打印函数a、伪代码实现:判断该链表是否为空链表,如果是,报错如果不是空链表,新建立一个temp指针将temp指针指向头结点打印temp指针的data域逐个往后移动temp指针,直到temp指针的指向的指针的next域为空b、代码实现void Linklist::show()//打印数组元素{Node*p=front->next;while(p){cout<<p->data<<" ";p=p->next;}}7.获取链表长度函数a、伪代码实现:判断该链表是否为空链表,如果是,输出长度0如果不是空链表,新建立一个temp指针,初始化整形数n为0将temp指针指向头结点判断temp指针指向的结点的next域是否为空,如果不是,n加一,否则return n使temp指针逐个后移,重复d操作,直到temp指针指向的结点的next域为0,返回nb 、代码实现void Linklist::Getlength()//得到数组长度{Node*p=front->next;int j=0;while(p){p=p->next;j++;}cout<<j;}2.3 其他源代码#include<iostream>using namespace std;struct Node{int data;struct Node* next;};class Linklist{public:Linklist(int a[],int n);Linklist(int a[],int n,int m);Node* Get(int i);void Insert(int x);int Delete(int i);int Locate(int x);void Getlength();void show();~Linklist();private:Node*front;};Linklist::Linklist(int a[],int n)//头插法{front=new Node;front->next=NULL;for(int i=n-1;i>=0;i--){Node*s=new Node;s->data=a[i];s->next=front->next;front->next=s;}}Linklist::Linklist(int a[],int n,int m)//尾插法{front=new Node;Node*r=front;for(int i=0;i<n;i++){Node*s=new Node;s->data=a[i];r->next=s;r=s;}r->next=NULL;}Node* Linklist::Get(int i)//得到指向第i个数的指针{Node*p=front->next;int j=1;while(p&&j!=i)//p非空且j不等于i,指针后移{p=p->next;j++;}return p;}void Linklist::Insert(int x)//将x按顺序插入{Node*p=front->next;if(!p)//如果链表为空,直接插入{Node*s=new Node;s->data=x;s->next=front->next;front->next=s;}elsewhile(!((p->next->data>x)&&(p->data<x)))//判断p的下一个结点的值大于x且p的值小于x{p=p->next;}Node*s=new Node;//将x插入到p之后s->data=x;s->next=p->next;p->next=s;}int Linklist::Delete(int i)//删除第i个位置的结点{Node*p=front;if(i!=1)p=Get(i-1);//得到第i-1个位置的指针Node*q=p->next;p->next=q->next;int x=q->data;delete q;return x;}int Linklist::Locate(int x)//得到值为x的位置{Node*p=front->next;int j=1;while(p){if(p->data==x)return j;p=p->next;j++;}return -1;}void Linklist::Getlength()//得到数组长度{Node*p=front->next;int j=0;while(p){p=p->next;j++;}cout<<j;}Linklist::~Linklist()//析构{Node*p=front;while(p){front=p;p=p->next;delete front;}}void Linklist::show()//打印数组元素{Node*p=front->next;while(p){cout<<p->data<<" ";p=p->next;}}void main()//主函数{int a[10]={1,2,3,4,5,6,7,8,9,11}; Linklist A(a,10);Linklist B(a,10,1);cout<<"原数组为:";A.show();cout<<endl;A.Insert(10);cout<<"插入操作后的数组变为:";A.show();cout<<endl;A.Delete(7);cout<<"删除操作后的数组为:";A.show();cout<<endl;A.Locate(1);cout<<"数组长度为:";A.Getlength();A.~Linklist();cout<<endl;}3. 程序运行结果1.测试主函数流程:2、运行结果4. 总结调试时出现的问题及解决的方法:在设计将x按顺序插入的函数时,没有分清p->next->next->data和 p->next->data的区别,通过认真查阅和理解书本知识解决。

相关文档
最新文档