实验一线性表
数据结构实验报告-线性表(顺序表实现)
实验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 线性表的基本操作一、需求分析目的:掌握线性表运算与存储概念,并对线性表进行基本操作。
1.初始化线性表;2.向链表中特定位置插入数据;3.删除链表中特定的数据;4.查找链表中的内容;5.销毁单链表释放空间;二、概要设计●基础题主要函数:初始化线性表InitList(List* L,int ms)向顺序表指定位置插入元素InsertList(List* L,int item,int rc)删除指定元素值的顺序表记录DeleteList1(List* L,int item)删除指定位置的顺序表记录 DeleteList2(List* L,int rc)查找顺序表中的元素 FindList(List L,int item)输出顺序表元素OutputList(List L)实验步骤:1,初始化顺序表2,调用插入函数3,在顺序表中查找指定的元素4,在顺序表中删除指定的元素5,在顺序表中删除指定位置的元素6,遍历并输出顺序表●提高题要求以较高的效率实现删除线性表中元素值在x到y(x和y自定义)之间的所有元素方法:按顺序取出元素并与x、y比较,若小于x且大于y,则存进新表中。
编程实现将两个有序的线性表进行合并,要求同样的数据元素只出现一次。
方法:分别按顺序取出L1,L2的元素并进行比较,若相等则将L1元素放进L中,否则将L 1,L2元素按顺序放进L。
本程序主要包含7个函数主函数main()初始化线性表InitList(List* L,int ms)向顺序表指定位置插入元素InsertList(List* L,int item,int rc)删除指定元素值的顺序表记录DeleteList1(List* L,int item)删除指定位置的顺序表记录 DeleteList2(List* L,int rc)查找顺序表中的元素 FindList(List L,int item)输出顺序表元素OutputList(List L)提高题的程序void Combine(List* L1,List* L2,List* L)void DeleteList3(List* L,int x,int y)二、详细设计初始化线性表InitList(List* L,int ms)void InitList(List* L,int ms){L->list=(int*)malloc(LIST_INIT_SIZE*sizeof(int));L->size=0;L->MAXSIZE=LIST_INIT_SIZE;}向顺序表指定位置插入元素InsertList(List* L,int item,int rc)void InsertList(List* L,int item,int rc){int i;if (L->size>=L->MAXSIZE){L->list=(int*)realloc(L->list,(L->MAXSIZE+LISTI)*sizeof(int));L->MAXSIZE+=LISTI;}for (i=L->size-1;i>=rc-1;i--){L->list[i+1]=L->list[i];}L->list[rc-1]=item;L->size++;}删除指定元素值的顺序表记录DeleteList1(List* L,int item)void DeleteList1(List* L,int item){int i,j;for (i=0;i<L->size;i++){if (L->list[i]==item){break;}}for (j=i;j<L->size;j++){L->list[j]=L->list[j+1];}L->size--;}删除指定位置的顺序表记录 DeleteList2(List* L,int rc)void DeleteList2(List* L,int rc){int i;for (i=rc-1;i<L->size;i++){L->list[i]=L->list[i+1];}L->size--;}查找顺序表中的元素void FindList(List* L,int item){int i;for (i=0;i<L->size;i++){if (L->list[i]==item)break;}if (L->size==i){printf("找不到\n");}else{printf("第%d个元素为%d\n",i+1,item); }}输出顺序表元素OutputList(List L)void OutputList(List* L){int i;for (i=0;i<L->size;i++){printf("%d ",L->list[i]);}printf("\n");}删除x到y之间的所有元素void DeleteList3(List* L,int x,int y){int i,j,temp;if (x>y)temp=x;x=y;y=temp;}for (i=0,j=0;i<L->size;i++){if (L->list[i]<x || L->list[i]>y){L->list[j]=L->list[i];j++;}}L->size=j;}将两个有序的线性表进行合并void Combine(List* L1,List* L2,List* L) {int i,j,k,temp;if (L1->size>L2->size){temp=L2->size;}else{temp=L1->size;i=0,j=0,k=0;while(1){if (i==L1->size || j==L2->size)break;if (L1->list[i]<L2->list[j]){L->list[k]=L1->list[i];k++;i++;}else if (L1->list[i]>L2->list[j]){L->list[k]=L2->list[j];k++;j++;}else{L->list[k]=L2->list[j];k++;j++;i++;}}if (i==L1->size){for (i=j;i<L2->size;i++,k++){L->list[k]=L2->list[i];}}else{for (j=i;j<L1->size;j++,k++){L->list[k]=L1->list[j];}}L->size=k;}三、调试分析体会:线性表内数据都是顺序排放所以实验中比较容易写出程序时间复杂度:初始化线性表InitList(List* L,int ms)⊙(1)向顺序表指定位置插入元素InsertList(List* L,int item,int rc)⊙(n)删除指定元素值的顺序表记录DeleteList1(List* L,int item) ⊙(n) 删除指定位置的顺序表记录 DeleteList2(List* L,int rc)⊙(n)查找顺序表中的元素 FindList(List L,int item)⊙(n)输出顺序表元素OutputList(List L)⊙(n)删除x到y之间的所有元素⊙(n)将两个有序的线性表进行合并⊙(n) 四、调试与结果测试。
数据结构-实验一 线性表操作
实验一线性表操作
(一)实验内容
单链表的创建、合并和输出。
(二)实验目的
1.熟悉用Visual C++进行程序设计的方法。
2.掌握单链表的创建、查找、插入和合并等运算。
(三)实验题目
本实验要求实现以下功能:
1.从键盘输入顺序任意的5个整数,按有序插入的要求生成第一个有序
单链表,将该链表输出显示。
2.再从键盘输入顺序任意的5个整数,按有序插入的要求生成第二个有
序单链表,将该链表输出显示。
3.将这两个有序单链表合并成一个有序单链表,要求使用两个单链表
的原有空间进行合并,将生成的有序单链表输出显示。
(四)实验仪器设备
1.学生每个一台PC机
2.已安装环境。
实验一 线性表的插入和删除
}
else{
p=find(head,k); //查找第k-1个结点,并由p指向该结点
p1=p->next;
p->next=p1->next;
delete p1;
system("cls");
cout<<"成功删除了第"<<k<<"个结点!\n";
}
return(head);
int i;
for(i=2;(i<k)||(p->next==NULL);i++)
{
if(p->next==NULL)
{
return NULL;
}
p=p->next;
}
return p;
}
}
node *insert(node *head,int a)
{
node *p1;
p1=new node;
p1->data=a;
while(!(cin>>k))//输入序号,若不为整数则重输
{
cerr << "输入错误!请重新输入:";
cin.clear();
cin.sync();
}
}
int j=1;
node *p,*p1;
p=head;
if (k==1){
p=head;
head=head->next;
delete p;
system("cls");
int a;
cout<<"建立一条有序链表,请输入数据,以-1结束:\n";
数据结构实验一-线性表
数据结构实验⼀-线性表实验⼀线性表⼀、实验⽬的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];/*将未完成的代码补全,提⽰:此处添加⼀条语句,将被删除元素之后的元素左移。
实验一 线性表基本操作
{
printf("申请空间失败");
return ERORR;
}
s->number=i;
printf("请输入第%d个人的密码:",i);
scanf("%d",&s->password);
t->next=s;
t=s;
}
t->next=NULL;
return (OK);
}
int Josephus(LinkList H,int m)
p1=InsList(p,e);
show(p1);
}
运行结果:
分析:该程序一共有三个子函数:InitList(int r)初始化顺序表、InsList (SeqList *L,ElemType e)插入元素、show(SeqList *L)显示顺序表。主函数先得到数序表的长度r,把r传给初始化函数,经输入和排序得到一个顺序表,返回表的收地址L。输入一个待插入数e,再调用插入函数把它插入到该顺序表中(先用for循环通过比较找到该插入的位置,在用for循环把后面的元素都向后移一位,再把e插入,最后last++),返回首地址L。最后在调用显示函数,输出插入后的顺序表
printf("请输入从哪开始删除:");
scanf("%d",&i);
printf("请输入删除的位数:");
scanf("%d",&k);
p1= DelList(p,i,a,k);
show(p1);
}
运行结果:
分析:该函数有三个子函数:InitList(int r)初始化顺序表、DelList (SeqList *L,int i,ElemType a[],int k)删除元素、show(SeqList *L)显示顺序表。主函数先得到数序表的长度r,把r传给初始化函数,经输入和排序得到一个顺序表,返回表的收地址L。输入要删除的首位置i和删除的位数k,再调用删除函数把该顺序表中的相应元素删掉(先用for循环删除这k个元素,在用for循环把后面的元素向前移,最后last-k),返回首地址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域为空,返回多个地址,那么在链表中如果存在多个待找元素都可以返回。
数据结构实验一实验报告——线性表
实验报告课程名称:数据结构实验名称:线性表班级:学生姓名:学号:指导教师评定:签名:题目:有两张非递增有序的线性学生表A,B,采用顺序存储结构,两张表合并用c表存,要求C为非递减有序的,然后删除C表中值相同的多余元素。
一、需求分析⒈本演示程序根据已有的两张表的信息,实现两张表的合并及删除值相同元素的操作,需要用户输入学生的信息。
⒉在演示过程序中,用户输入需要合并的顺序表,即可观看合并结果。
⒊程序执行的命令包括:(1)构造线性表A (2)构造线性表B (3)求两张表的并(4)删除C中值相同的元素二、概要设计⒈为实现上述算法,需要线性表的抽象数据类型:ADT Stack {数据对象:D={a i:|a i∈ElemSet,i=1…n,n≥0}数据关系:R1={<a i-1,a i>|a i-1,a i∈D,i=2,…n≥0}基本操作:init(list *L)操作结果:构造一个空的线性表L。
ListLength(List *L)初始条件:线性表L已经存在操作结果:返回L中数据元素的个数。
GetElem(List L, int i, ElemType *e)初始条件:线性表L已经存在,1≤i≤ListLength(&L)操作结果:用e返回L中第i个数据元素的值。
EqualList(ElemType *e1,ElemType *e2)初始条件:数据元素e1,e2存在操作结果:以e1,e2中的姓名项作为判定e1,e2是否相等的依据。
Less_EquaList(ElemType *e1,ElemType *e2)初始条件:数据元素e1,e2存在操作结果:以e1,e2中的姓名项(为字符串)的≤来判定e1,e2是否有≤的关系。
LocateElem(List *La,ElemType e,int type)初始条件:线性表La已经存在操作结果:判断La中是否有与e相同的元素。
MergeList(List *La,List *Lb,List *Lc)初始条件:非递减线性表La,Lb已经存在操作结果:合并La,Lb得到Lc,Lc仍按非递减有序排列。
实验一 线性表及其应用
实验一线性表及其应用
一、实验目的
1.熟悉C语言的上机环境,进一步掌握C语言的结构特点。
2.掌握线性表的顺序存储结构的定义及C语言实现。
3.掌握线性表的链式存储结构——单链表的定义及C语言实现。
4.掌握线性表在顺序存储结构即顺序表中的各种基本操作。
5.掌握线性表在链式存储结构——单链表中的各种基本操作。
二、实验内容
1.顺序线性表的建立、插入及删除。
2.链式线性表的建立、插入、删除、求链表长、两个链表合并等。
三、实验步骤
1.建立含n个数据元素的顺序表并输出该表中各元素的值及顺序表的长度。
2.利用前面的实验先建立一个顺序表L={21,23,14,5,56,17,31},然后在第i个位置插入元素68。
3.建立一个带头结点的单链表,结点的值域为整型数据。
要求将用户输入的数据按尾插入法来建立相应单链表。
四、思考与提高
如果按由表尾至表头的次序输入数据元素,应如何建立顺序表。
数据结构实验一题目一线性表实验报告
数据结构实验报告实验名称:实验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的区别,通过认真查阅和理解书本知识解决。
实验一 线性表的建立与应用
实验一线性表的建立与应用一实验目的:通过实验,了解并掌握线性表逻辑特性和物理特性,了解并掌握队列和栈的运算方法,培养结合理论知识进行实际应用的实践能力。
二实验内容:队列示意图队列也是一种运算受限制的线性表,它的运算包括:初始化队、入队、退队、读取队首和队尾的数据。
当队列为空时不允许退队,当队列未满的时候不允许入队。
在实际应用中,通常使用循环队列循环队列示意图初始化循环队列四、实验步骤1 进入Turbo C 2.0,新建一个文件。
2 输入程序,程序要求使用子函数进行组织。
3 将源程序保存到指定文件夹“D:\学生姓名”。
4 按F9调试,纠正语法错误。
5按Ctrl+F9运行,调试逻辑错误。
6 按Alt+F5查看结果。
五、实验中应注意的问题与思考题:五、实验中应注意的问题与思考题:1 在对栈和队列的运算过程中保证数据结构的逻辑完整性。
2 栈和循环队列元素的打印。
在打印过程中应该正确分析循环队列的具体情况,做到正确打印。
3 栈与队列均不允许在中间插入数据,保证运算的正确性;线性队列不能重复使用,不符合流程化要求,应采取循环队列。
4 当栈满,而此时要进行退队入栈运算时应进行怎样的处理才能避免数据的丢失?退队入栈时,判断栈是否为满:若为满,则把数据存到其他地方。
5 当队列满,而此时要进行退栈入队运算时应进行怎样的处理才能避免数据的丢失?退栈入队时,判断队列是否为满:若为满,则把数据存到其他地方。
6 应用程序要求循环执行,每次运算结束后要求打印栈和队列中的元素,以查看结果。
7 对各个功能模块采用独立编制子函数,增强程序的可执行性、可移植性和可读性。
增加情报信息量,对实际应用中可能发生的情况考虑周全,对非法情形要提出适当的处理方案。
六、源程序#include "stdlib.h"#include "stdio.h"void push(s,m,top,x) /*******入栈************/int s[],x; int m,*top;{if(*top==m) {printf("栈上溢\n");return;}*top=*top+1;s[*top-1]=x;return;}void pop(s,m,top,y) /************退栈************/int s[],*y; int m,*top;{if(*top==0) {printf("栈下溢\n");return;}*y=s[*top-1];*top=*top-1;return;}out_s(s,m,top) /************输出栈内元素******************/int s[],m,*top;{int *q;q=s+*top-1;printf("输出栈内元素: ");if(q>=s)while(q>=s){ printf("%d ",*(q--)); }else printf("没有元素!!!");printf("\n"\n ");return;}void addcq(q,m,rear,front,s,x) /**************入队******************/int q[],x; int m,*rear,*front,*s;{if((*s==1)&&(*rear==*front)){printf("队列上溢\n");return;}*rear=*rear+1;if(*rear==m+1) *rear=1;q[*rear-1]=x;*s=1;return;}void delcq(q,m,rear,front,s,y) /**************退队*****************/int q[],*y; int m,*rear,*front,*s;{if(*s==0) {printf("队列下溢\n");return;}*front=*front+1;if(*front==m+1) *front=1;*y=q[*front-1];if(*front==*rear) *s=0;return;}out_q(q,m,front,rear,s) /******************输出队内元素******/ int q[],m,*front,*rear,*s;{int k;k=(*front)%m;*front=(*front)%m;*rear=(*rear)%m;printf("输出队列内元素: ");if(*s==1){if(*front<*rear)while(k<*rear){ printf("%d ",q[k]);k++;}else{while(k<=m-1){ printf("%d ",q[k]);k++;}k=0;while(k<*rear){ printf("%d ",q[k]);k++;}}}else { printf("没有元素!!!"); }printf("\n\n ");}main(){int x,y,z,m,n,*s,*q,top,rear,front,l,i,k,j;l=0;m=5;n=5;s=malloc(m*sizeof(int));q=malloc(n*sizeof(int));top=0;rear=n;front=n;printf("输入0, 退出\n");printf("输入1, 压栈\n");printf("输入2, 入队\n");printf("输入3, 弹栈\n");printf("输入4, 退队\n");printf("输入5, 弹栈入队\n");printf("输入6, 退队压栈\n");printf("输入0-6:");scanf("%d",&y);for(;y!=0;){switch(y){case 1:{printf("输入压栈元素\n");scanf("%d",&x);push(s,m,&top,x);out_s(s,m,&top);out_q(q,n,&front,&rear,&l);break;}case 2: {printf("输入入队元素");scanf("%d",&y);addcq(q,n,&rear,&front,&l,y);out_s(s,m,&top);out_q(q,n,&front,&rear,&l);break;}case 3:{pop(s,m,&top,&i);out_s(s,m,&top) ;out_q(q,n,&front,&rear,&l);break;}case 4: {delcq(q,n,&rear,&front,&l,&k);out_s(s,m,&top);out_q(q,n,&front,&rear,&l);break;}case 5:{if(top==0){ pop(s,m,&top,&i);out_s(s,m,&top);out_q(q,n,&front,&rear,&l);break;}pop(s,m,&top,&i);addcq(q,n,&rear,&front,&l,i);out_s(s,m,&top);out_q(q,n,&front,&rear,&l);break;}case 6:{if(l==0){ delcq(q,n,&rear,&front,&l,&k);out_s(s,m,&top);out_q(q,n,&front,&rear,&l);break;}delcq(q,n,&rear,&front,&l,&k);push(s,m,&top,k);out_s(s,m,&top);out_q(q,n,&front,&rear,&l);break;}default:break;}printf("输入0, 退出\n");printf("输入1, 压栈\n");printf("输入2, 入队\n");printf("输入3, 弹栈\n");printf("输入4, 退队\n");printf("输入5, 弹栈入队\n");printf("输入6, 退队压栈\n");printf("输入0-6:");scanf("%d",&y);}free(q);free(s);}七、实验总结通过实验,了解并掌握了线性表逻辑特性和物理特性,了解并掌握了队列和栈的运算方法,培养了结合理论知识进行实际应用的实践能力,受益匪浅。
实验一线性表操作实验报告
实验一_线性表操作_实验报告实验一:线性表操作一、实验目的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.帮助读者复习C++语言程序设计中的知识。
2.熟悉线性表的逻辑结构。
3.熟悉线性表的基本运算在两种存储结构上的实现。
4.掌握顺序表的存储结构形式及其描述和基本运算的实现。
5.熟练掌握动态链表结构及有关算法的设计二、实验内容题目一: 顺序表的基本操作[问题描述]实现顺序表的建立、求长度, 取元素、修改元素、插入、删除等顺序表的基本操作。
[基本要求](1)依次从键盘读入数据, 建立带头结点的顺序表;(2)输出顺序表中的数据元素(3)求顺序表的长度;(4)根据指定条件能够取元素和修改元素;(5)实现在指定位置插入和删除元素的功能。
(6)根据算法, 将两个有序的顺序表合并成一个有序顺序表。
[测试数据] 由学生任意指定。
题目二: 单链表的基本操作[问题描述]实现带头结点的单链表的建立、求长度, 取元素、修改元素、插入、删除等单链表的基本操作。
[基本要求](1)依次从键盘读入数据, 建立带头结点的单链表;(2)输出单链表中的数据元素(3)求单链表的长度;(4)根据指定条件能够取元素和修改元素;(5)实现在指定位置插入和删除元素的功能。
(6)根据算法, 将两个有序的单链表合并成一个有序单链表。
[测试数据]由学生任意指定。
三、源代码顺序表的基本操作#include<iostream>using namespace std;#define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define OVERFLOW -2typedef int Status;typedef int ElemType;#define LIST_INIT_SIZE 100#define LISTINCREMENT 10typedef struct { //结构体ElemType *elem;int length;int listsize;}SqList;SqList Lx;Status InitList_Sq(SqList &L) //分配空间{ L.elem=new ElemType[LIST_INIT_SIZE];if(!L.elem)exit(OVERFLOW);L.length =0;L.listsize=LIST_INIT_SIZE;return OK;}Status ListInsert(SqList &L,int i,ElemType e) //插入新元素{ int *q,*p;ElemType *newbase;if(i<1 || i>L.length+1) return ERROR;if(L.length>=L.listsize){ newbase=new ElemType[L.listsize+LISTINCREMENT];if(!newbase) exit(OVERFLOW);L.elem=newbase;L.listsize+=LISTINCREMENT;}q=&(L.elem[i-1]);for (p=&(L.elem[L.length-1]);p>=q;--p)*(p+1)=*p;*q=e;++L.length;return OK;}Status Listlength(SqList L) //长度{ int *p=L.elem; //判断线形表是否存在while(p){ return (L.length); }}Status GetElem(SqList L, int i,ElemType &e) //取元素{ if(i<1 || i>L.length)return ERROR;else{ e=L.elem[i-1];return e;}}void MergeList(SqList La,SqList Lb,SqList &Lc) //合并{ ElemType ai,bj;InitList_Sq(Lc);int i=1,j=1,k=0;int La_len,Lb_len;La_len=Listlength(La);Lb_len=Listlength(Lb);while((i<=La_len)&&(j<=Lb_len)){ GetElem(La,i,ai);GetElem(Lb,j,bj);if(ai<=bj){ ListInsert(Lc,++k,ai);++i; }else{ ListInsert(Lc,++k,bj);++j; }}while(i<=La_len){ GetElem(La,i++,ai);ListInsert(Lc,++k,ai);}while(j<=Lb_len){ GetElem(Lb,j++,bj);ListInsert(Lc,++k,bj);}}void show(SqList L,int i) //显示{ int j;ElemType k;cout<<"顺序表显示如下:"<<endl;for(j=0;j<i-1;j++){ k=L.elem[j];cout<<k<<"->"; }if(j==i-1 && i>0){ k=L.elem[j]; cout<<k; }cout<<endl;}void create(SqList &L,int n) //输入元素{ int e;for(int i=0;i<n;i++){ cin>>e;L.elem[i]=e;L.length=i+1; }}Status ListDelete_Sq(SqList &L,int i,ElemType &e) //删除{ ElemType *p, *q;if(i<1 || i>L.length) return ERROR;p=&(L.elem[i-1]);e=*p;q=L.elem+L.length-1;for(++p;p<=q;++p) *(p-1)=*p;--L.length;return OK;}Status Listxiugei(SqList &L,int i,ElemType &e) //修改{ if(i<1 || i>L.length)return ERROR;else{ L.elem[i-1]=e;return OK; }}void shuru(SqList &L1) //顺序表的创建{ int a;InitList_Sq(L1);cout<<"请输入顺序表的长度: ";cin>>a;cout<<"请输入顺序表的元素(共"<<a<<"个)"<<endl;create(L1,a);show(L1,a);}void chaxun(SqList &L1) //取第i个位置的元素{ int j;ElemType e1;cout<<"请选择所要取出元素的位置:";cin>>j;while(j<0||j>Listlength(L1)){ cout<<"输入有误, 请重新输入"<<endl;cout<<"请选择所要取出元素的位置:";cin>>j; }GetElem(L1,j,e1);cout<<"取出的元素为:"<<e1<<endl; }void xiugai(SqList &L1) //修改第i个位置的元素{ int a;int j; ElemType e1;a=L1.length;cout<<"请选择所要修改元素的位置:";cin>>j;while(j<0||j>Listlength(L1)){ cout<<"输入有误, 请重新输入"<<endl;cout<<"请选择所要修改元素的位置:";cin>>j; }cout<<"要修改成的元素:";cin>>e1;Listxiugei(L1,j,e1);cout<<"修改后的顺序表数据:"<<endl;show(L1,a);}void shanchu(SqList &L1) //删除顺序表里的元素{ int a;int j; ElemType e1;a=L1.length;cout<<"请选择所要删除元素的位置:";cin>>j;while(j<0||j>Listlength(L1)){ cout<<"输入有误, 请重新输入"<<endl;cout<<"请选择所要删除元素的位置:";cin>>j; }ListDelete_Sq(L1,j,e1);cout<<"修改后的顺序表数据:"<<endl;show(L1,a-1);}void charu(SqList &L1) //插入元素到顺序表里{ int a; int j; ElemType e1;a=L1.length;cout<<"请选择所要插入元素的位置:";cin>>j;while(j<0||j>Listlength(L1)){ cout<<"输入有误, 请重新输入"<<endl;cout<<"请选择所要插入元素的位置:";cin>>j; }cout<<"要插入的元素:";cin>>e1;ListInsert(L1,j,e1);cout<<"修改后的顺序表数据:"<<endl;show(L1,a+1);}void hebing(SqList &L3) //合并两个顺序表{ SqList L1,L2;int a,b;InitList_Sq(L1); InitList_Sq(L2);cout<<"请输入第一个有序表的长度: "; cin>>a;cout<<"请输入第一个有序表的元素(共"<<a<<"个)"<<endl;create(L1,a);show(L1,a);cout<<"请输入第二个有序表的长度: "; cin>>b;cout<<"请输入第二个有序表的元素(共"<<b<<"个)"<<endl;create(L2,b);show(L2,b);MergeList(L1,L2,L3);cout<<"合并后的有序表如下: "; show(L3,a+b);}void main() //主菜单{ int choice;for(;;){ cout<<" 顺序表的基本操作"<<endl;cout<<" 1.顺序表的创建"<<endl;cout<<" 2.顺序表的显示"<<endl;cout<<" 3.顺序表的长度"<<endl;cout<<" 4.取第i个位置的元素"<<endl;cout<<" 5.修改第i个位置的元素"<<endl;cout<<" 6.插入元素到顺序表里"<<endl;cout<<" 7.删除顺序表里的元素"<<endl;cout<<" 8.合并两个顺序表"<<endl;cout<<" 9.退出系统"<<endl;cout<<"请选择: ";cin>>choice;switch(choice){ case 1: shuru(Lx);break;case 2: show(Lx,Lx.length);break;case 3: cout<<"顺序表的长度:"<<Listlength(Lx)<<endl;break;case 4: chaxun(Lx);break;case 5: xiugai(Lx);break;case 6: charu(Lx);break;case 7: shanchu(Lx);break;case 8: hebing(Lx);break;case 9: cout<<"退出系统!"<<endl;exit(0);break;default : cout<<"输入有误, 请重新选择"<<endl;break; } }}单链表的基本操作#include<iostream>using namespace std;#define true 1#define false 0#define ok 1#define error 0#define overflow -2typedef int Status;typedef int ElemType;typedef struct LNode //存储结构{ ElemType data;struct LNode *next;}LNode,*LinkList;void CreateList(LinkList &L,int n) //尾插法创建单链表{ LinkList p;L=new LNode;L->next=NULL; //建立一个带头结点的单链表LinkList q=L; //使q指向表尾for(int i=1;i<=n;i++){ p=new LNode;cin>>p->data;p->next=NULL;q->next=p;q=p; }}Status GetElem(LinkList L,int i,ElemType &e)//取第i个元素{ LinkList p=L->next;int j=1;while(p&&j<i){ p=p->next;++j; }if(!p||j>i) return error; //第i个元素不存在e=p->data;return ok;}Status LinkInsert(LinkList &L,int i,ElemType e) //插入{ LinkList p=L;int j=0;while(p&&j<i-1){ p=p->next;++j; } //寻找第i-1个结点if(!p||j>i-1)return error; //i小于1或者大于表长加1 LinkList s=new LNode; //生成新结点s->data=e;s->next=p->next; //插入L中p->next=s;return ok;}Status ListDelete(LinkList &L,int i,ElemType &e) // 删除{ LinkList p=L;LinkList q;int j=0;while(p->next&&j<i-1){ //寻找第i个结点, 并令p指向其前驱p=p->next;++j; }if(!(p->next)||j>i-1) return error; //删除位置不合理q=p->next;p->next=q->next; //删除并释放结点e=q->data;delete(q);return ok;}void MergeList(LinkList &La,LinkList &Lb,LinkList &Lc){ //合并两个顺序链表LinkList pa,pc,pb;pa=La->next;pb=Lb->next;Lc=pc=La;while(pa&&pb){ if(pa->data<=pb->data){ pc->next=pa;pc=pa;pa=pa->next; }else{ pc->next=pb;pc=pb;pb=pb->next; }}pc->next=pa?pa:pb;delete(Lb);}void show(LinkList L) //显示{ LinkList p;p=L->next;while(p){ cout<<p->data<<"-->";p=p->next; }cout<<endl;}int Length(LinkList L,int i) //表长{ i=0;LinkList p=L->next;while(p){ ++i;p=p->next; }return i;}void xiugai(LinkList L) //修改{ int i,j=1;ElemType k;ElemType e,m;LinkList p=L->next;cout<<"请输入要修改的元素位置(0<i<length):";cin>>i;GetElem(L,i,e);cout<<"该位置的元素:"<<e<<endl;cout<<"修改后的元素值:";cin>>k;while(p&&j<i){ p=p->next;++j; }m=p->data;p->data=k;cout<<"修改后的单链表显示如下:"<<endl;show(L);}void hebing() //合并两个单链表{ int a,b;LinkList La,Lb,Lc;cout<<"请输入第一个有序链表的长度:"<<endl;cin>>a;cout<<"请输入第一个有序链表的元素共("<<a<<"个): "<<endl;CreateList(La,a);show(La);cout<<"请输入第二个有序链表的长度:"<<endl;cin>>b;cout<<"请输入第二个有序链表的元素共("<<b<<"个): "<<endl;CreateList(Lb,b);show (Lb);MergeList(La,Lb,Lc);cout<<"合并后的有序链表如下: "<<endl;show(Lc);}void main() //主函数{ int select;int x;ElemType y;LinkList list;for(;;){ cout<<" 单链表的基本操作"<<endl;cout<<" 1.单链表的创建"<<endl;cout<<" 2.单链表的显示"<<endl;cout<<" 3.单链表的长度"<<endl;cout<<" 4.取第i个位置的元素"<<endl;cout<<" 5.修改第i个位置的元素"<<endl;cout<<" 6.插入元素到单链表里"<<endl;cout<<" 7.删除单链表里的元素"<<endl;cout<<" 8.合并两个单链表"<<endl;cout<<" 9.退出系统"<<endl;cout<<"请选择:";cin>>select;switch(select){ case 1:cout<<"请输入单链表的长度:"<<endl;cin>>x;cout<<"请输入"<<x<<"个元素"<<endl;CreateList(list,x);break;case 2: cout<<"单链表显示如下:"<<endl;show(list);break;case 3: int s;cout<<"单链表的长度为:"<<Length(list,s)<<endl;break;case 4: cout<<"请选择所要取出元素的位置:";cin>>x;while(x<0||x>Length(list,s)){ cout<<"输入有误, 请重新输入"<<endl;cout<<"请选择所要取出元素的位置:";cin>>x; }GetElem(list,x,y);cout<<"该位置的元素为:"<<y<<endl;break;case 5: xiugai(list); break;case 6: cout<<"请选择要插入的位置:"; cin>>x;while(x<0||x>Length(list,s)){ cout<<"输入有误, 请重新输入"<<endl;cout<<"请选择所要插入元素的位置:";cin>>x; }cout<<"要插入的元素值:";cin>>y;LinkInsert( list,x,y);cout<<"插入后单链表显示如下:"<<endl;show(list);break;case 7: cout<<"请选择要删除的位置:"; cin>>x;while(x<0||x>Length(list,s)){ cout<<"输入有误, 请重新输入"<<endl;cout<<"请选择所要删除元素的位置:";cin>>x; }ListDelete(list,x,y);cout<<"要删除的元素值:"<<y<<endl;cout<<"删除后的单链表显示如下:"<<endl;show(list);break;case 8: hebing();break;case 9: exit(0);break;default : cout<<"输入有误, 请重新输入"<<endl;break;}}}四、测试结果顺序表的测试结果单链表的测试结果五、心得体会当听到老师说写数据结构实验报告时, 我有点惊讶, 才学了不到一个月, 就要写实验报告。
实验一 线性表的顺序实现及操作
实验一 线性表的顺序实现及操作一、实验目的1.掌握用上机调试线性表顺序实现的基本方法。
2.掌握线性表的基本操作,插入、删除、查找等运算在顺序存储结构上的实现。
二、实验要求1.认真阅读和分析实验内容。
2.设计顺序线性表操作的算法。
3.编程实现这些算法。
4.上机调试程序,结合程序进行分析,打印出文件清单和运行结果。
三、实验内容1.线性表顺序存储的物理结构(如图所示)① Elem :存储存放表元素连续内存空间的首地址;② Length :存储Elem 所指空间中存放的元素个数;③ ListSize :存储Elem 空间的大小,该大小值以元素个数为单位来体现;④ 注意,在线性表的逻辑结构中,元素在线性表中的位置次序是从1开始计数的; ⑤ 线性表L 实质是一个具有三个域的结构类型的变量。
2.编程实现如下要求:定义出该线性表物理结构;初始化顺序存储的线性表;销毁线性表;将线性表重新设置为空表;判断线性表是否为空表;返回线性表的长度;在线性表中插入一个元素;在线性表中删除一个元素;取线性表中第i 个元素的值;在线性表中查找参数Elem 值所给定的元素;将线性表中指定位置的元素值修改成指定的值。
3.代码示例// 以下代码书写在SqList.h 文件中。
#include <stdlib.h> // 一般将系统头文件用< >括起来,自定义头文件用" "括起来。
#define LIST_INIT_SIZE 50#define LIST_INCREMENT 50//typedef int ListElemType;// 该类型的定义也可以在该头文件的外部来定义,这样在使用线性表结构时,可以尽可能少地 // 改动该头文件内的代码。
// 顺序线性表数据类型的定义。
该定义是对所设计的物理结构的编程语言描述。
typedef struct{ListElemType *Elem; // 存放一片连续内存空间的首地址,该空间中存放线性表元素值。
实验一--线性表的实验
实验一--线性表的实验实验一线性表的实验实验课程名: C语言程序设计专业班级:学号:姓名实验时间:实验地点:指导教师:一、实验目的及要求1、掌握用Visual C++6.0调试顺序表的基本方法。
2、掌握顺序表的基本操作,插入、删除、查找、以及有序顺序表的合并等算法的实现。
3、掌握用Visual C++6.0上机调试单链表的基本方法。
4、掌握单链表的插入、删除、查找、求表长以及有序单链表的合并算法的实现。
5、进一步掌握循环单链表的插入、删除、查找算法的实现。
}SeqList;void InitSeqList( SeqList *L){char flag;int i,n;ElemType *p;L->list=( ElemType * )malloc(MaxSize*sizeof( ElemType ));L->length=0 ;L->size=MaxSize ;printf("是否输入初始数据?(Y/N)");scanf("%c",&flag);if(flag=='N'||flag=='n') return;printf("请输入初始化数据的个数:");scanf("%d",&n);if(n>L->size) {printf("数据太多,不足以存储!");return;}p=L->list;L->length=n;for(i=0;i<n;i++){printf("请输入第%d个数据(学号姓名性别(0或1)联系电话QQ号):\n",i+1);scanf("%s%s%d%s%s",p->xuehao,p->name , &p->sex ,p->tel ,p->qq );p++;}return;}void PrintSeqList(SeqList *L){int i;printf("学号姓名性别联系电话QQ号\n");for( i=0 ; i<L->length ; i++ ){printf("%s\t%s\t",L->list[i].xuehao,L->list[i].name );if(L->list[i].sex)printf("男");else printf("女");printf("\t%s\t%6s\n", L->list[i].tel ,L->list[i].qq );}}/*int main(){SeqList L;InitSeqList( &L );PrintSeqList( &L );return 0;}*/ int InsertSeqList(SeqList *L,int i,ElemType *e){ElemType *q,*p;if(L->length+1>L->size ) {printf("表满,失败!");return 0;}if(i<1||i>L->length+1) {printf("插入位置错误,失败!");return 0;} q=&(L->list[i-1]);for(p=&(L->list[L->length-1]);p>=q;p--)*(p+1)=*p ;*(p+1)=*e;L->length++;return 1;}/*int main(){ElemType e;SeqList L;InitSeqList(&L);PrintSeqList(&L);printf("请输入要插入的数据(学号姓名性别(0或1)联系电话QQ 号):\n");scanf("%s%s%d%s%s",e.xuehao, , &e.sex , e.tel ,e.qq ); printf("学号姓名性别联系电话QQ号\n");printf("%s\t%s\t",e.xuehao, );if(e.sex)printf("男");else printf("女");printf("\t%s\t%6s\n", e.tel ,e.qq ); InsertSeqList(&L,2,&e);PrintSeqList(&L);return 0;}*/int LocateList(SeqList *L,char *x){int i=0;while(i<L->length &&strcmp(L->list[i].xuehao ,x ))++i;if(i<L->length ){printf("\n学号姓名性别联系电话QQ号\n");printf("%s\t%s\t",L->list[i].xuehao,L->list[i].name);if(L->list[i].sex) printf(" 男"); else printf(" 女");printf("%s\t%6s\n",L->list[i].tel,L->list[i].qq);return i+1;}return 0;}/*int main(){SeqList L;InitSeqList(&L);PrintSeqList(&L);printf("输出查询结果:\n");LocateList(&L,"02");return 0;}*/int DeleteList(SeqList *L,int i){int j;ElemType *q,*p;if(L->length ==0) {printf("表空,删除失败!\n");return 0;}if(i<1||i>L->length) {printf("删除位置错,失败!\n");return 0;} p=&(L->list[i-1]);for(q=&(L->list[L->length-1]);q<=p;p--)*(p-1)=*p;L->length --;return 1;}int main(){int i;SeqList L; InitSeqList(&L); PrintSeqList(&L);printf("请输入删除位数:"); scanf("%d",&i); DeleteList(&L,i); PrintSeqList(&L); return 0;}(2)运行结果:2.插入功能3.查询功能4.删除功能(3)运行结果分析:本次作业利用C语言实现顺序表初始化、插入、删除、查找、的基本操作。
数据结构实验一-线性表
实验一线性表学生姓名吴肖遥学号20151681310131 专业班级电子信息5班实验地点理工大楼610 实验日期2016.3.21 指导教师李红蕾实验环境Visual c++6.0 实验学时2学时实验类型综合实验成绩一、实验目的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<stdio.h>#include<stdlib.h>#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;i<L->length;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.掌握数据结构中的一些基本概念。
数据、数据项、数据元素、数据类型和数据结构,以及它们之间的关系。
2.了解数据的逻辑结构和数据的存储结构之间的区别与联系;数据的运算与数据的逻辑结构的关系。
3.掌握线性表的基本操作:插入、删除、查找以及线性表的合并等运算。
4.掌握运用C语言上机调试线性表的基本方法。
二、实验条件1.硬件:一台微机2.软件:操作系统和C语言系统三、实验方法确定存储结构后,上机调试实现线性表的基本运算。
四、实验内容1.试编写在无头结点的单链表上实现线性表基本运算LOCATE(L,X),INSERT (L,X,1)和DELETE(L,1)的算法。
2.假设有两个按数据元素值递增有序排列的线性表A和B,均以单链表作为存储结构。
编写算法将A表和B表归并成一个按元素值递减有序(即非递增有序,允许值相同)排列的线性表C,并要求利用原表(即A表和B表)结点空间存放表C。
3.将一个线性表中的值就地逆置。
4.在线性表的顺序存储结构的第一个位置上插入一个元素。
五、实验算法及运行结果#include<iostream>using namespace std;template<class T>class sqlist //顺序表类{private:int m,n;T* v;public:sqlist(){m=0;n=0;return;}sqlist(int x){m=x;v=new T(m);n=0;return;}void prt(){int i;cout<<"长度为"<<n<<':'<<endl;for(i=0;i<n;i++)cout<<v[i]<<'\t';cout<<endl;return;}void inst( int x,int i){ int j;if(n==m){ cout<<"overflow"<<endl;return;} elseif((i<1)||(i>n+1)){cout<<"error"<<endl;return;}else{ for (j=n;j>i-1;j--)v[j]=v[j-1];v[i-1]=x;n++;return;}}};template<class T> //线性链表结点struct node{T d;node* next;};template<class T> //线性链表类class lklist{private:node<T>*head;public:lklist(){head=NULL;return;}void prt(){node<T>*p;p=head;if(p==NULL){cout<<"空链表!"<<endl;return;}do{cout<<p->d<<'\t';p=p->next;}while(p!=NULL);cout<<end l;return;}void inst(T x,T b){node<T>*p,*q;p=new node<T>;p->d=b;if(head==NULL){head=p;p->next=NULL;return;}if(head->d==x){p->next=head;head=p;return;}q=head;while((q->next!=NULL)&&(((q->next)->d)!=x))q=q->next;p->next=q->next;q->next=p;return;}void delt(T x){node<T>*p,*q;if(head==NULL){cout<<"链表空,无要删的元素"<<endl;return;}if((head->d)==x){p=head->next;delete head;head=p;cout<<x<<"已删除"<<endl;return;}q=head;while((q->next!=NULL)&&(((q->next)->d)!=x))q=q->next;if(q->next=NULL){cout<<"链表中无要删的元素"<<endl;return;}p=q->next;q->next=p->next;delete p;cout<<x<<"已删除"<<endl;return;}void locate(T x){node<T>*p;p=head;int i=1;while (p->next != NULL){if (p->d==x){cout<<x<<"在第"<<i<<"个节点"<<endl;return ;} else{i++;p=p->next;}}if(p->d!= x)cout<<"无此结点"<<endl;return;}void connectlink(lklist A,lklist B){node<T>*p,*q,*m;p=A.head;q=B.head;this->head=NULL;while((p!= NULL) &&(q!= NULL)){ if (p->d< q->d){ m=p;A.head=(A.head)->next;p=A.head;}else{ m=q;B.head=(B.head)->next;q=B.head;}m->next=this->head;this->head=m;}while(p!=NULL){ m=p; A.head=(A.head)->next; p=A.head;m->next=this->head;this->head=m;}while(q!=NULL){ m=q; B.head=(B.head)->next; q=B.head;m->next=this->head;this->head=m;}}};void main(){lklist<int> A,B,C;A.inst(55,50);A.inst(50,40);A.inst(40,30);A.inst(30,20);A.inst(20,10);cout<<"链表A:"<<endl;A.prt();B.inst(35,25);B.inst(25,15);B.inst(15,5);cout<<"链表B:"<<endl;B.prt();C.connectlink(A,B);cout<<"按递减方式连接A和B得到链表C:"<<endl;C.prt();cout<<"在C中查找30:"<<endl;C.locate(30);C.delt(50);cout<<"删除50后C为:"<<endl;C.prt();int a[ ]={1,2,3,4,5,6,7,8},i; /* 将线性表以顺序存储方式存放*/void Converse(int a[ ], int n); /* 函数说明*//* 程序主体*/cout<<"原数组序列为: "<<endl;for (i=0;i<8;i++)cout<<'\t'<<a[i];cout<<endl;Converse(a,8); /* 函数调用*/cout<<"逆序数组序列为: "<<endl;for (i=0;i<8;i++)cout<<'\t'<<a[i];cout<<endl;sqlist<int> S(10);S.inst(9,1);S.inst(4,2);S.inst(17,3);cout<<"建立顺序表S";S.prt();S.inst(25,1);cout<<"在顺序表S的第一个位置上插入25后,S"; S.prt();}void Converse(int a[ ], int n){ int m, x, i ;m=n/2;for (i=0;i<m;i++){ x=a[i];a[i]=a[n-1-i];a[n-1-i]=x;}}。
实验1 线性表的基本操作
ElemType *p=L.elem+1;
while(i<=L.length&&*p!=cur_e)
{
p++;
i++;
}
if(i>L.length)
return*--p;
return 1;
}
}
int NextElem(SqList L,ElemType cur_e,ElemType &next_e)
int i;
p=L.elem;
for(i=1;i<=L.length;i++)
vi(*p++);
cout<<endl;
return 1;
} void print(ElemType &c) {
printf("%d ",c); } // 线性表的单链表存储结构 struct LNode { ElemType data; LNode *next; }; typedef LNode *LinkList; // 另一种定义LinkList的方法 // 操作结果:构造一个空的线性表L Status InitList(LinkList &L) { L=(LinkList)malloc(sizeof(LNode)); // 产生头结点,并使L指向此头结点 if(!L) // 存储分配失败
// 操作结果:用e返回L中第i个数据元素的值 if(i<1||i>L.length)
exit(1); e=*(L.elem+i-1); return 1; } int equal(ElemType c1,ElemType c2) { // 判断是否相等的函数,Union()用到 if(c1==c2)
实验一线性表.docx
本科实验报告课程名称:数据结构实验项目:线性结构、树形结构、图结构、查找、排序实验地点:逸夫楼502专业班级:软件1223班学号:2012005646 学生姓名:王萌指导教师:杨崇艳2013年11 月20日实验一线性表一.目的与要求1.实习的主要目的:2.要求:二.例题○1问题描述 :○2输入:○3输出:○4存储结构:○5算法的基本思想:○6程序:#define NULL 0typedef struct node{char a;struct node *link;}node,*nodelink;void readlink(nodelink head){nodelink p,q;char c;p=head;printf("Input a linktable(a string):");scanf("%c",&c);if (c=='\n') printf("This string is empty。
");while(c!='\n'){q=(nodelink)malloc(sizeof(node));q->a=c;p->link=q;p=q;scanf("%c",&c);}p->link=NULL;}void writelink(nodelink head){nodelink q;if (head->link==NULL) printf(" This link is empty。
\n");for(q=head->link;q;q=q->link)printf("%c",q->a);printf("\n");}int insert(nodelink head,char k1,char k2){nodelink p,q;p=head->link;while(p->a!=k1&&p)p=p->link;if(p){q=(nodelink)malloc(sizeof(node));q->a=k2;q->link=p->link;p->link=q;return 1;}else {printf("There is no %c\n",k1);return 0;}}int delete(nodelink head,char k){nodelink p,q;q=head;p=head->link;while(((p->a)!=k)&&p){q=q->link;p=p->link;}if(p){q->link=p->link;return 1;}else{printf("There is no %c\n",k);return 0;}}void opside(nodelink head){nodelink p,q;p=head->link;while(p->link){q=p->link;p->link=q->link;q->link=head->link;head->link=q;}}main(){char k1,k2,k3;nodelink head;head=(nodelink)malloc(sizeof(node));head->link=NULL;readlink(head);if (head->link!=NULL){printf("Build link is :");writelink(head); }if (head->link!=NULL){printf("Please input a char you want to insert after:");k1=getch();printf("%c\n",k1);printf("Please input a char you want to insert:");k2=getch();printf("%c\n",k2);if (insert(head,k1,k2)) {printf("After %c insert %c,link is:",k1,k2);writelink(head);}printf("Please input a char you want to delete:");k3=getch();printf("%c\n",k3);if (delete(head,k3)){ printf("after delete %c,link is:",k3);writelink(head);}if (head->link!=NULL){printf("Opsite result is :");opside(head);writelink(head);free(head);}}}○7调试结果:○8程序的优缺点、时空性能以及改进思想,写出心得体会。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验一线性表的基本操作及其应用
一、实验目
1、帮助读者复习C++语言程序设计中的知识。
2、熟悉线性表的逻辑结构。
3、熟悉线性表的基本运算在两种存储结构上的实现,其中以熟悉链表的操作为侧重点。
二、实验内容和要求
[问题描述]
设计一个算法,以实现一元稀疏多项式的加法运算。
[基本要求]
(1)输入并建立多项式;
(2)输出多项式,输出形式为整数序列:n,c1,e1,c2,e2,……,cn,en,其中n是多项式的项数,ci和ei分别是第i项的系数和指数,序列按指数降序排列;
(3)多项式a和b相加,建立多项式a+b。
[测试数据]
由学生任意指定。
[实现提示]
用带表头结点的单链表存储多项式。
[选作内容]
多项式a和b相减,建立多项式a-b。
三、算法设计
1、主要思想:根据多项式的结构特点,利用链表来实现多项式相加,多项式中的每一项为单链表中的一个结点,每个结点包含三个域:系数域、指数域和指针域,其形式如下:
现在设有两个多项式:A(x)=12+3x2+5x3+8x4
B(x)=5+6x5
它们的链表结构见图1所示。
图1 多项式的单链表结构
多项式相加的运算规则为:两个多项式中所有指数相同的项,对应系数相加,若和不为零,则构成“和多项式”中的一项;所有指数不同的项均复制到“和多项式”中。
实现时,可采用另建多项式的方法,也可采用把一个多项式归并到另一个多项式中去的方法。
这里介绍后一种方法。
2、本程序包含四个模块
1)主函数
void main(){
初始化;
建立两个链表A和B;
输出建立的链表;
A与B的相加,并输出
}
2)建立多项式函数CreatPoly()——根据用户输入的项数,提示用户输入系数和指数,建立链式存储的一元多项式
3)输出多项式函数outpoly()——根据日常的阅读习惯将多项式按格式输出
4)多项式相加函数PolyAdd ()——按照多项式相加的法则实现两个多项式的相加
核心算法多项式相加PolyAdd()是把分别由pa和pb所指的两个多项式相加,结果为
pa所指的多项式。
相加时,首先设两个指针变量qa和qb分别从多项式的首项开始扫描(见图1),比较qa和qb所指结点指数域的值,可能出现下列三种情况之一:(1)qa->exp大于qb->exp,则qa继续向后扫描。
(2)qa->exp等于qb->exp,则将其系数相加。
若相加结果不为零,将结果放入qa->coef 中,并删除qb所指结点,否则同时删除qa和qb所指结点。
然后qa、qb继续向后扫描。
(3)qa->exp小于qb->exp,则将qb所指结点插入qa所指结点之前,然后qa、qb继续向后扫描。
扫描过程一直进行到qa或qb有一个为空为止,然后将有剩余结点的链表接在结果链表上。
所得pa指向的链表即为两个多项式之和。
算法CreatPoly()是建立表示多项式的单链表。
建立链表的过程是一个动态生成的
过程,即从“空表”的初始状态起,依次输入数据元素,每输入一个就生成一个新结点并插入到表尾。
为了方便新结点的插入,算法中设置一个指针pre使其始终指向当前链表的表尾结点,初始指向pa(见图1)。
各模块之间的调用关系及接口如下:
3、元素类型、结点类型和指针类型
typedef int ElemType;
typedef struct mulpoly{
ElemType coef;
ElemType exp;
struct mulpoly * next;
} mulpoly;
4、主函数和其他函数清单
struct mulpoly * CreatePoly(int n) //根据用户输入的项数n,提示用户输入n组系数和指
数,并构建链式线性表存储多项式信息{ }
void OutPoly(mulpoly * head)// 将以head为头指针的链表按多项式的格式输出
{ }
struct mulpoly * PolyAdd (mulpoly * pa, mulpoly *pb)// 将以pa,pb为头指针的两个链表按多项式相加的法则进行合并,放在pa中,并将pa返回
void main()
{ }
四、调试分析
1、在建立链表和多项式相加时,新生成链表的头指针做为参数传递时,曾忽略了参数的标识“&”,致使建立链表失败。
后来为了减少参数传递的个数,将新生成链表的头指针做为函数结果返回。
今后应重视参数的变量和赋值属性的区别和标识。
2、本程序的模块划分比较合理,对指针的操作封装在子函数中,致使集合模块的调试比较顺利。
但在子函数addpoly中,由于当前尾指针r赋了错误的初值,致使溢出,以后在编程和调试中都要进一步注意。
3、算法设计欠周全,对于输入数据的合法性没有检查;在输入多项式项的过程中,默认用户按降幂次序输入多项式各项,造成使用不方便和健壮性较差,所以应进一步修改多项式的建立操作,将新输入的项与已建成的链表部分进行比较,根据幂次的大小插入到正确的位置。
4、算法的时空分析
1)有序表采用带头结点的有序单链表,并增设尾指针,各种算法的时间复杂度比较合理,
插入多项式结点的时间复杂度为O(1),多项式相加的时间复杂度为O(m+n)。
2)算法另设结点存放多项式的和,空间复杂度为O(m+n)。
4、空间复杂度较大,因此可以改进算法,在原来的链表上摘取结点,这样可以减少或无需另外结点生成。
五、实验结果
1.分别输入两个多项式: 5X3+4X2+3X+2 和X2+X+1,然后输出结果如图1所示。
2.分别输入两个多项式:6X4+4X2+2和5X+6,然后输出结果如图2所示。
图2 实验结果
六、总结
此次上机实验应用了线性表实现了一次实际操作,完成了一个一元多项式
的简单计算器,不仅对此次编译程序的算法思想有了新的认识,还让我深刻的
体会到了线性表的重要性以及其应用的方便,并且对指针加深了映象,应用了
书本中的算法思想,对我以后的编译以及完成新的程序有很大的帮助。
七、源程序(带注释)
……。