收藏 分销(赏)

数据结构实验指导手册.doc

上传人:w****g 文档编号:3896321 上传时间:2024-07-23 格式:DOC 页数:56 大小:130.54KB 下载积分:14 金币
下载 相关 举报
数据结构实验指导手册.doc_第1页
第1页 / 共56页
数据结构实验指导手册.doc_第2页
第2页 / 共56页


点击查看更多>>
资源描述
实验一 线性表的顺序存储实验 一、实验目的 1、掌握用Visual C++6.0上机调试顺序表的基本方法 2、掌握顺序表的基本操作,插入、删除、查找、以及有序顺序表的合并等算法的实现 二、实验内容 1、顺序表基本操作的实现 [问题描述] 当我们要在顺序表的第i个位置上插入一个元素时,必须先将顺序表中第i个元素之后的所有元素依次后移一个位置,以便腾空一个位置,再把新元素插入到该位置。若是欲删除第i个元素时,也必须把第i个元素之后的所有元素前移一个位置。 [基本规定] 规定生成顺序表时,可以键盘上读取元素,用顺序存储结构实现存储。 [实现提醒] 要实现基本操作,可用实现的基本操作,也可设计简朴的算法实现。 [程序实现] #include <stdio.h> #include <conio.h> typedef int DataType ; # define maxnum 20 typedef struct {int data[maxnum]; int length; }SeqList; /*插入函数*/ int insert(SeqList *L , int i , DataType x) /* 将新结点x插入到顺序表L第i个位置 */ { int j ; if( i<0 || i>(*L).length +1) { printf(" \n i 值不合法 ! "); return 0; } if((* L).length >=maxnum-1) { printf(" \n 表满不能插入!"); return 0; } for(j=(*L).length;j>=i;j--) (*L).data[j+1]=(*L).data[j]; (*L).data[i] = x; (*L).length++; return 1; } /*删除函数*/ int delete( SeqList *L ,int i) /*从顺序L中删除第i个结点*/ { int j ; if( i<0|| i>(*L).length ) { printf(" \n 删除位置错误 ! ") ; return 0; } for(j=i+1;j<=(*L).length;j++) (*L).data[j-1] =(*L).data[j]; (*L).length--; return 1; } /*生成顺序表*/ void creatlist(SeqList * L) { int n , i , j ; printf("请输入顺序表 L 的数据个数:\n") ; scanf("%d" , &n) ; for(i=0 ; i<n ; i++) { printf("data[%d] =" , i) ; scanf("%d",&((*L).data[i])); } (*L).length=n-1; printf("\n") ; }/*creatlist */ /*输出顺序表 L*/ printout(SeqList * L) { int i ; for (i=0 ; i<=(* L).length ; i++) { printf(" data[%d]=", i) ; printf("%d", (*L).data[i]); }/*printout */ printf("\n"); } main() { SeqList *L ; char cmd ; int i , t , x; clrscr() ; creatlist(L); do { printf("\ni , I ----- 插入\n") ; printf("d , D ----- 删除\n") ; printf("q , Q ----- 退出\n") ; do {cmd=getchar() ; }while((cmd!='i')&&(cmd!='I')&&(cmd!='d')&&(cmd!='D')&&(cmd!='q')&&(cmd!='Q')); switch(cmd) { case 'i': case 'I': printf("\nPlease input the DATA: "); scanf("%d",&x) ; printf("\nWhere? "); scanf("%d",&i) ; insert(L,i,x) ; printout(L); break ; case 'd': case 'D' : printf("\nWhere to Delete? "); scanf("%d",&i); delete(L,i); printout(L); break ; } }while((cmd!='q')&&(cmd!='Q')); } 2、有序顺序表的合并 [问题描述] 已知顺序表la和lb中的数据元素按非递减有序排列,将la和lb表中的数据元素,合并成为一个新的顺序表lc [基本规定] lc中的数据元素仍按非递减有序排列,并且不破坏la和lb表 [程序实现] # include <stdio.h> # define maxnum 20 typedef int DataType ; typedef struct { DataType data[maxnum] ; int length ; }SeqList ; int MergeQL(SeqList la , SeqList lb , SeqList *lc) { int i , j , k ; if (la.length+1 + lb.length+1>maxnum) { printf("\narray overflow!") ; return 0; } i=j=k=0; while(i<=la.length && j<=lb.length) { if (la.data[i]<=lb.data[j]) lc->data[k++]=la.data[i++] ; else lc->data[k++]=lb.data[j++]; } /* 解决剩余部分 */ while (i<=la.length) lc->data[k++]=la.data[i++]; while (j<=lb.length) lc->data[k++]=lb.data[j++]; lc->length=k-1; return 1; } main() { SeqList la={{3,4,7,12,15},4} ; SeqList lb={{2,5,7,15,18,19},5} ; SeqList lc ; int i ; if (MergeQL(la,lb,&lc)) { printf("\n") ; for(i=0;i<=lc.length ; i++) printf("%4d",lc.data[i]); } } 实验二 单链表实验 一、实验目的 1、掌握用Visual C++6.0上机调试单链表的基本方法 2、掌握单链表的插入、删除、查找、求表长以及有序单链表的合并算法的实现 二、实现内容 1、单链表基本操作的实现 [问题描述]要在带头结点的单链表h中第i个数据元素之前插入一个数据元素x ,一方面需要在单链表中寻找到第i-1个结点并用指针p指示,然后申请一个由指针s 指示的结点空间,并置x为其数据域值,最后修改第i-1个结点,并使x结点的指针指向第i个结点,要在带头结点的单链表h中删除第i个结点,一方面要计数寻找到第i个结点并使指针p指向其前驱第i-1个结点,然后删除第i个结点并释放被删除结点空间。 [基本规定]用链式存储结构实现存储 [实现提醒]链式存储结构不是随机存储结构,即不能直接取到单链表中某个结点,而要从单链表的头结点开始一个一个地计数寻找。 [程序实现] # include <stdio.h > # include <malloc.h > typedef char DataType ; typedef struct node{ DataType data; /*结点的数据域*/ struct node *next; /*结点的指针域*/ }ListNode; void Init_List(ListNode **L) { (*L)=(ListNode *)malloc(sizeof(ListNode));/*产生头结点*/ (*L)->next=NULL; } int List_Length(ListNode *L ) { int n=0;ListNode *p=L->next; while(p!=NULL) { n++; p=p->next; } return n; } ListNode* GetNode(ListNode *L,int i) { int j; ListNode *p; p=L;j=0; /*从头结点开始扫描*/ while(p->next&&j!=i) /*顺指针向后扫描,直到p->next为NULL或i=j为止*/ { p=p->next; j++; } if(i==j) return p; /*找到了第i个结点*/ else return NULL; /*当i<0或i>0时,找不到第i个结点*/ } void InsertList(ListNode *L,DataType x,int i) { ListNode *p,*s; p=GetNode(L,i-1); /*寻找第i-1个结点*/ if (p==NULL) /*i<1或i>n+1时插入位置i有错*/ { printf("position error"); return ; } s=(ListNode *)malloc(sizeof(ListNode)); s->data=x;s->next=p->next;p->next=s; } void DeleteList(ListNode *L ,int i) { ListNode *p,*r; p=GetNode(L,i-1); /*找到第i-1个结点*/ if (p==NULL||p->next==NULL) /*i<1或i>n时,删除位置错*/ { printf("position error"); return ; } r=p->next; /*使r指向被删除的结点a*/ p->next=r->next; /*将ai从链上删除*/ free(r); } /*使用头插法建立带头结点链表算法*/ ListNode * CreatListF(void) { char ch; ListNode *head=(ListNode *)malloc(sizeof(ListNode)); /*生成头结点*/ ListNode *s; /*工作指针*/ head->next=NULL; ch=getchar(); /*读入第1个字符*/ while(ch!='\n') { s=(ListNode *)malloc(sizeof(ListNode)); /*生成新结点*/ s->data=ch; /*将读入的数据放入新结点的数据域中*/ s->next=head->next; head->next=s; ch=getchar(); /*读入下一字符*/ } return head; } /*使用尾插法建立带头结点链表算法*/ ListNode * CreatListR1(void) { char ch; ListNode *head=(ListNode *)malloc(sizeof(ListNode)); /*生成头结点*/ ListNode *s,*r; /*工作指针*/ r=head; /*尾指针初值也指向头结点*/ while((ch=getchar())!='\n') { s=(ListNode *)malloc(sizeof(ListNode)); s->data=ch; r->next=s; r=s; } r->next=NULL; /*终端结点的指针域置空,或空表的头结点指针域置空*/ return head; } /*复制链表A中的内容到表B中*/ void copy(ListNode *a, ListNode *b) { ListNode *pa=a->next; ListNode *u; ListNode *rb=b; while(pa!=NULL) { u=( ListNode *)malloc(sizeof(ListNode)); u->data=pa->data; rb->next=u; rb=u; pa=pa->next; } rb->next=NULL; } /*输出带头结点的单链表*/ void DisplaySL(ListNode *la, char *comment) { ListNode *p ; p=la->next ; if(p) printf("\n%s\n" , comment) ; while(p) { printf("%4c",p->data); p=p->next; } printf("\n") ; } /*主函数*/ main( ) { ListNode *la ,*lb,*lc, *p ; int n,x,i; printf("\n用头插法建立链表la,请输入节点内容:"); la=CreatListF(); DisplaySL(la,"新生成链la节点内容:"); printf("\n链表la的长度: %2d",List_Length(la)); printf("\n请输入要插入的元素: "); scanf("%c",&x) ; printf("\n请输入要插入的位置:"); scanf("%d",&i) ; InsertList(la,x,i); DisplaySL(la,"插入后链la节点内容"); printf("\n请输入要删除元素的位置:"); scanf("%d",&i); DeleteList(la,i); DisplaySL(la, "删除后链la节点内容"); printf("\n用尾插法建立链表lb,请输入节点内容:"); fflush(stdin); lb=CreatListR1(); DisplaySL(lb,"新生成链lb节点内容:"); Init_List(&lc); copy(la,lc); DisplaySL(lc,"复制生成的链lc节点内容:"); } 2、有序单链表的合并 [问题描述] 已知单链表la和lb中的数据元素按非递减有序排列,将la和lb中的数据元素,合并为一个新的单链表lc,lc中的数据元素仍按非递减有序排列。 [基本规定] 不破坏la表和lb表的结构。 [程序实现] # include <stdio.h> #include<alloc.h> #define NULL 0 typedef int DataType; typedef struct SLNode { DataType data; struct SLNode * next; }slnodetype; int MergeSL(slnodetype *la,slnodetype *lb,slnodetype **lc); int CreateSL(slnodetype *la,int n); void DisplaySL(slnodetype *la , char * comment); main( ) { slnodetype *la, *lb, *lc ,*p; int n,m; la=(slnodetype *)malloc(sizeof(slnodetype)); la->next=NULL; lb=(slnodetype *)malloc(sizeof(slnodetype)); lb->next=NULL; lc=(slnodetype *)malloc(sizeof(slnodetype)); lc->next=NULL; printf("\n 输入链la节点数:"); scanf("%d",&n); printf("\n 输入链la 节点内容:"); CreateSL(la,n); DisplaySL(la,"链la 节点内容:"); printf("\n 输入链lb节点数:"); scanf("%d",&m); printf("\n 输入链lb节点内容:"); CreateSL(lb,m); DisplaySL(lb,"链lb 节点内容:"); if(MergeSL(la,lb,&lc)) DisplaySL(lc,"合成后的链lc:"); getchar(); } int MergeSL(slnodetype * la , slnodetype *lb,slnodetype * *lc) { slnodetype * pa, * pb, * pc; lc=(slnodetype *)malloc(sizeof(slnodetype)); pa=la->next; pb=lb->next; pc= *lc; while(pa&&pb) { pc->next=(slnodetype*)malloc(sizeof(slnodetype)); pc=pc->next; if(pa->data<=pb->data) { pc->data=pa->data; pa=pa->next; } else{ pc->data=pb->data; pb=pb->next; } } while (pa) /*插入la链的剩余段 */ { pc->next=(slnodetype*)malloc(sizeof(slnodetype)); pc=pc->next; pc->data=pa->data; pa=pa->next; } /*插入lb链的剩余段*/ while(pb) { pc->next=(slnodetype*)malloc(sizeof(slnodetype)); pc=pc->next; pc->data=pb->data; pb=pb->next; } /*生成单链表*/ int CreateSL(slnodetype *la ,int n) { int i ; slnodetype *p , *q ; q=la ; for (i=1 ; i<=n ; i++) { p=(slnodetype *)malloc(sizeof(slnodetype)); scanf("%d" , &p->data) ; q->next=p; q=p; } q->next=NULL ; return 1 ; } /*输出单链表*/ void DisplaySL(slnodetype *la, char *comment) { slnodetype *p ; p=la->next ; if(p) printf("\n%s\n" , comment) ; while(p) { printf("\n%3d" , p->data); p=p->next ; } printf("\n") ; } 实验三 循环链表实验 一、实验目的 1、掌握用Visual C++6.0上机调试循环链表的基本方法 2、进一步掌握循环单链表的插入、删除、查找算法的实现 二、实现内容 1. 约瑟夫环问题 [问题描述]设有N个人围坐一圈,现从某个人开始报数,数到M的人出列,接着从出列的下一个人开始重新报数,数到M的人以出列,如此下去,直到所有人都出列为此。试设计拟定他们的出列顺序序列的程序。 [基本规定] 选择单向循环链表作为存储结构模拟整个过程,并依次输出列的各人的编号。 [实现提醒] 程序运营之后,一方面规定用户指定初始报数的下限值,可以n<=30,此题循环链表可不设头节点,并且必须注意空表和非空表的界线。 如 n=8, m=4 时,若从第一个人, 设每个人的编号依次为 1,2,3,…开始报数,则得到的出列顺序为4,8,5,2,1,3,7,6, 如下图所示,内层数字表达人的编号 ,每个编号外层的数字代表人出列的序号。 [程序实现] #include <stdio.h> #include <malloc.h> typedef struct node { int num; struct node *next; }linklist; linklist *creat(head,n) /*使n个人围成一圈,并给每个人标记号数*/ linklist *head; int n ; {linklist *s,*p; int i; s=(linklist * )malloc(sizeof(linklist)); head=s; s->num=1; p=s; for(i=2;i<=n; i++) { s=(linklist *) malloc(sizeof(linklist)); s->num=i; p->next=s; p=s; } p->next=head; return(head); }/* creat */ linklist * select(linklist *head, int m) { linklist *p, *q; int i, t; p=head; t=1; q=p; /* q为p的前趋指针*/ p=p->next; do { t=t+1 ; /*报一次数*/ if(t%m==0) { printf("%4d", p->num); q->next=p->next; free(p); p=q->next; } else { q=p; p=p->next; } }while(q!=p); head=p; printf("%4d",p->num); return (head); }/* select */ main( ) { int n,m; linklist *head; printf("\ninput the total number:n="); scanf("%d", &n); printf("\ninput the number to call:m="); scanf("%d", &m); head=creat(head,n); head=select(head,m); printf("\nthe last one is :%d", head->num); }/* main */ 思考题:编程实现两个循环单链表的合并。 实验四 栈、队列的实现及应用 一、实验目的 1、掌握栈和队列的顺序存储结构和链式存储结构,以便在实际背景下灵活运用。 2、掌握栈和队列的特点,即先进后出与先进先出的原则。 3、掌握栈和队列的基本操作实现方法。 二、实验内容 1、实现栈的顺序存储 # define MAXSIZE 100 typedef int ElemType; typedef struct { ElemType data[MAXSIZE]; int top; }SeqStack; void InitStack(SeqStack *s) {s->top=0; return 1; } int StackEmpty(SeqStack *s) { if(s->top==0) return 1; else return 0; } int StackFull(SeqStack *s) { if(s->top==MAXSIZE-1) return 1; else return 0; } void Push(SeqStack *s,int x) { if (StackFull(s)){ printf("the stack is overflow!\n"); return 0; } else { s->data[s->top]=x; s->top++; } } void Display(SeqStack *s) {if(s->top==0) printf("the stack is empty!\n"); else{ while(s->top!=0) { printf("%d->",s->data[s->top]); s->top=s->top-1; } } } ElemType Pop(SeqStack *s) { if(StackEmpty(s)) return 0; else return s->data[--s->top]; } ElemType StackTop(SeqStack *s) { int i; if(StackEmpty(s)) return 0; else { i=s->top-1; return s->data[i];} /*返回栈顶元素的值,但不改变栈顶指针*/ } main(SeqStack *p) {int n,i,k,h,x1,x2,select; printf("create a empty stack!\n"); InitStack(p); printf("input a stack length:\n"); scanf("%d",&n); for(i=0;i<n;i++) { printf("input a stack value:\n"); scanf("%d",&k); Push(p,k); } printf("select 1:Display()\n"); printf("select 2:Push()\n"); printf("select 3:Pop()\n"); printf("select 4:StackTop()\n"); printf("input a your select(1-4):\n"); scanf("%d",&select); switch(select) {case 1:{ display(p); break;} case 2:{ printf("input a push a value:\n"); scanf("%d",&h); Push(p,h); display(p); break;} case 3:{ x1=Pop(p); printf("x1->%d\n",x1); display(p); break; } case 4:{ x2=StackTop(p); printf("x2->%d",x2); break; } } } 2、运用栈实现数制转换 # define MAXSIZE 100 typedef int ElemType; /*将顺序栈的元素定义为整型*/ typedef struct { ElemType data[MAXSIZE]; int top; }SeqStack; void InitStack(SeqStack *s) {s->top=0; return 1; } int StackEmpty(SeqStack *s) { if(s->top==0) return 1; else return 0; } int StackFull(SeqStack *s) { if(s->top==m-1) return 1; else return 0; } void Push(SeqStack *s,int x) { if (StackFull(s)){ printf("the stack is overflow!\n"); return 0; } else { s->data[s->top]=x; s->top++; } } ElemType Pop(SeqStack *s) { ElemType y; if(StackEmpty(s)){ printf("the stack is empty!\n"); return 0; } else { y=s->data[s->top]; s->top=s->top-1; return y; } } ElemType StackTop(SeqStack *s) { if(StackEmpty(s)) return 0; else return s->data[s->top]; } void Dec_to_Ocx (int N) /* n是非负的十进制整数,输出等值的八进制数*/ { SeqStack *S; /*定义一个顺序栈*/ ElemType x; Init_SeqStack(S); /*初始化栈*/ if(N<0) { printf("\nError,The number must be over 0。"); return; } if(!N) Push(S,0); while(N) /*自右向左产生八进制的各位数字,并将其进栈*/ { Push(S,N%8); /*余数入栈 */ N=N/8; /*商作为被除数*/ } printf("Number %d converted to OCT:",N); while(StackEmpty(S)) /*栈非空时退栈输出*/ { x=Pop(S); printf(“%d”,x); } printf("\n"); } main( ) { int n; printf("Input a number to convert to OCT:\n"); scanf("%d",&n); Dec_to_Ocx (n); } 3、实现循环队列的顺序存储 #define maxsize 100 typedef struct {int data[maxsize]; int front; int rear; }seqqueue; int sqinit(seqqueue *p) { p->front=0;p->rear=0; return 1;} int enqueue(seqqueue *q, int e) {if((q->rear+1)%maxsize==q->front) return 0; else q->data[q->rear]=e; q->rear=(q->rear+1)%maxsize; return 1; } int dequeue(seqqueue *q) {int e; if (q->front==q->rear) return 0; e=q->data[q->front]; q->front=(q->front+1)%maxsize; return e; } int empty(seqqueue *q) {int v; if (q->front==q->rear) v=1; else v=0; return v; } int gethead(seqqueue *q) {int e; if (q->front==q->rear) e=-1; else e=q->data[q->front]; return e; } void display(seqqueue *q) {int s; s=q->front; printf("the sequeue is display:\n"); if (q->front==q->rear) printf("the sequeue is empty!
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 包罗万象 > 大杂烩

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2025 宁波自信网络信息技术有限公司  版权所有

客服电话:4009-655-100  投诉/维权电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服