数据结构实验

这篇博客介绍了三个数据结构实验:如何建立二叉排序树并进行中序遍历,栈的基本操作包括顺序栈的实现,以及堆排序的原理和程序实现。作者通过这些实验深化了对树、栈和排序算法的理解。
摘要由CSDN通过智能技术生成

姓名:樊进润         学号:2103101024          班级:计科211

实验一 二叉排序树的建立

一、【算法描述】

二叉排序树通常采用二叉链表作为存储结构。中序遍历二叉排序树便可得到一个有序序列,一个无序序列可以通过构造一棵二叉排序树变成一个有序序列,构造树的过程即是对无序序列进行排序的过程。

二、【实验内容】

编写能够通过键盘输入建立二叉排序树,并在建立完立即在屏幕显示中序遍历结果的程序

三、【程序代码】

#include<stdio.h>
#include<stdlib.h>
#define MAX 5
typedef struct Bnode
{
int key;
struct Bnode *left;
struct Bnode *right;
}Bnode;
Bnode * btInsert(int x,Bnode *root);
void Inorder(Bnode *root);
void main()
{
int i;
int a[MAX]={60,40,70,20,80};
Bnode * root=NULL;
printf("按关键字序列建立二叉排序树\n"); .
for(i=0;<MAX;i++) printf("%d ",a[i]);
printf("\n");
for(i=0;i<MAX;++) root=btInsert(a[i],root);
printf("中序遍历的二叉排序树\n"); 
Inorder(root);
printf("n");
}
Bnode * btInsert(int x,Bnode * root)
{
Bnode *p,*q;
int flag=0;
p=(Bnode *)malloc(sizeof(Bnode));
p->key=x;
p->right=p->left=NULL;
if(root==NULL)
{ root=p; return p; }
q=root;
while(flag==0)
{
if(q->key>x)
{
if(q->left!=NULL)
q=q->left;
else
{
q->left=p;
flag=1;
     }
}
else
{
if(q->right!=NULL)
q=q->right;
else
{
q->right=p;
flag=1;
      }
   }
}
return root;
}
void Inorder(Bnode *root)
if(root!=NULL)
{
Inorder(root->left);
printf("%d ",root->key);
Inorder(root->right);
    }
}

四、【输出结果】

五、【实验总结】

通过本次试验,对树的知识还是有了更深层次的了解,比如如何去构建一棵二叉排序树,平时简建树的算法才用递归的算法,但是二叉排序树是有规律的树,对加深了递归算法了解

实验二 栈的基本操作

一、【算法描述】

栈是一个线性表,栈中元素具有前驱后继的线性关系。栈中元素按照 a 1 a_1a 
1 , a 2 a_2a 2 , … , a n a_na n 的次序依次进栈。栈顶元素为a n a_na n

【实验内容】

栈的顺序表示和实现
顺序栈利用一组地址连续的存储单元依次存放自栈底到栈顶的数元素,同时附设指针top指示栈顶元素在顺序栈中的位置,利用一位数组实现栈的顺序存放。初始化顺序栈,

三、【程序代码】

#include <stdio.h>
#include <malloc.h>
#define MaxSize 100
typedef char ElemType;
typedef struct
{
ElemType data[MaxSize];
int top;        //栈 顶指针
} SeqStack;        //定义栈
typedef struct
{ElemType elem[MaxSize];
int front,rear;  //队首和队尾指针
} SqQueue:   //定义队列
//--初始栈函数
void InitStack(SeqStack *&s)
{
s=(SeqStack *)malloc(sizeof(SeqStack));
s->top=-1;
}
//---进栈函数
int Push(SeqStack *&s,ElemType e)
{
if (s->top==MaxSize- 1)
return 0;
s->top++;
s->data[s->top]=e;
return 1;
}
//--显示栈函数
void DispStack(SeqStack *s)
{
int i; .
for (i=s->top;i>=0;--)
printf("%c ",s->data[i]);
printf("\n"); 
}
//--显示栈底元素
void DispBottomStack(SeqStack *s)
printf("%c ",s->data[)];//先进后出,栈底元素为第一个 元素,即data[0] 
printf("\n"); .
/--判空栈函数
int StackEmpty(SeqStack *s)
{
return(s->top==-1);
}
//--出栈函数
int Pop(SeqStack *&s,ElemType &e)
{
if(s->top==-l)
return 0;
e=s->data[s->top];
s->top--;
return 1;
}
//--初始队列函数
void InitQueue(SqQueue *&q)
{
q=(SqQueue *)malloc (sizeof(SqQueue));
q-> front=q->rear=0;
}
//-入队列函数
int InQueue(SqQueue *&q,ElemType e)
{
if ((q->rear+ 1)%MaxSize==q->front)//队满
return 0;
q->rear=(q->rear+ 1)%MaxSize; 
q->elem[q->rear]=e;
return 1;
//--出队列函数
int OutQueue(SqQueue *&q.ElemType &e)
{
if(q-> front== =q->rear) //队空
return 0;
q->front=(q-> front+ 1)%MaxSize; .
e=q->elem[q-> front]; 
return 1;
}
//--判空队列函数
int QueueEmpty(SqQueue *q)
{
return(q->front= = =q->rear);
}
//--主程序.
void main()
{
ElemType e; 
SeqStack *s;
printf("(1)初始化栈s\n");
InitStack(s);
printf("(2)栈为%s\n",(StackEmpty(s)?"空":"非空"));
printf("(3)依次进栈元素a,b,c,d,e\n"); 
Push(s,’a’);//入栈元素1
Push(s,’b’);//入栈元素2
Push(s,’c’);//入栈元素3
Push(s,’d’);//入栈元素4
Push(s,’e’);//入栈元素5
printf("(4)栈为%s\n&apos; ,(StackEmpty(s)?"空":"非空));
printf("(5)从栈顶到栈底元素:");DispStack(s);
printf("(6)栈底元素为:");DispBottomStack(s); 
printf("(7)出栈/入队列序列:");
SqQueue *q;
InitQueue(q);
while (!StackEmpty(s))
{
Pop(s,e);//出栈
printf("%c ",e);
InQueue(q.e);//入队
}
printf("\n"); .
printf("(8)栈为%s," ,(StackEmpty(s)?"空":"非空)); .
printf("队列为%s\I",(QueueEmpty(q)?"空""非空");
printf("(9)出队列/入栈序列:");
while (!QueueEmpty(q))
{ 
OutQueue(q,e);//出 队
Push(s,);//入栈
printf("%c ",e);
}
printf("\n");
printf("(10)栈为%s,",(StackEmpty(s)?"空":"非空));
print("队列为%s\n",(QueueEmpty(q)?"空":"非空));
free(q);//释放队列
printf("(11)从栈顶到栈底元素:"):DispStack(s);
free();//释放栈
}

四、【输出结果】

 

五、【实验总结】

本次实验中学会了顺序栈和链栈的各个功能和操作,通过实验栈得到了更加深刻的认识和更完善的运用。

实验三 堆排序

一、【实验目的】

堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为O它也是不稳定排序。堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆, 每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆。

二、【实验内容】

(1)建立包含10个数据序列的堆(数据元素的值由自己设定) ;
(2)完成堆排序运算的程序;
(3)给出程序和堆排序前后的结果。

二、【程序代码】

#include <stdio.h>
#define N 8
struct NODE 
{
int date;
};
void heapshift(struct NODE a[],int i,int n)
{
struct NODE temp;
intj; 
temp=a[i];
j=2*i; 
while(j<n)
{
if(j+1<n && a[j].date >a[j+1].date )
j++;
if(temp.date >a[j].date )
{
a[i]=a[j]; .
i=j;
j=2*i;
}
else
break;
}
a[j]=temp; 
}
void heapsort(struct NODE a[],int n)
{
int i;
struct NODE temp;
for(i=n/2;i>=1;--)
heapshif(a,i,n);
for(i=n;i>1;--)
{
temp=a[1]; .
a[1]=a[i];
a[i]=temp;
heapshif(a,1,-1);
    }
}
void main()
{
struct NODE b[N]={40,80,65, 100, 14,30,55,50};
struct NODE a[N];
int i;
printf("初始数据序列: ");
for(i=0;i<N;i++)
{
a[i+ 1].date =b[j].date ;
}
for(i= 1;i<=N;i++){
print("%d " ,a[i].date);
}
printf("\n");
print("\n");
heapsort(a,N);
printf("堆排序后的数据序列: ");
for(i=1;i<=N;i++){
printf("%d ",a[i].date);
}
printf("\n");
}

五、【实验总结】

排序算法有很多,堆排序是其中之一,比如有冒泡排序,快速排序,插入排序等,每个算法都自己的优缺点,学习完堆排序和编写完堆排序的程序后,对堆排序有了更深层次的理解,此次编程还是遇到了些许问题,但是通过查阅,还是能够完成。

顺序存储的线性表 时数 2 性质 验证 内容:1、设线性表存放在向量A[arrsize]的前elenum个分量中,且递增有序。试设计一算法,将x插入到线性表的适当位置上,以保持线性表的有序性。 2、用向量作存储结构,试设计一个算法,仅用一个辅助结点,实现将线性表中的结点循环右移k位的运算。 3、用向量作存储结构,试设计一个算法,仅用一个辅助结点,实现将线性表逆置的运算。 要求:了解线性表的逻辑结构特征,熟练掌握线性表的顺序存储结构的描述方法,及在其上实现各种基本运算的方法。 单链表上的操作 时数 2 性质 验证 内容:1、已知带头结点的动态单链表L中的结点是按整数值递增排序的,试写一算法将值为x的结点插入到表L中,使L仍然有序。 2、设计一算法,逆置带头结点的动态链表L。要求利用原表的结点空间,并要求用尽可能少的时间完成。 3、假设有两个按元素值递增有序的线性表A和B,均以单链表作存储结构,试编写算法将A表和B表归并成一个按元素值递减有序的线性表C,并要求利用原表的空间存放C。 要求:熟练掌握线性表的单链式链接存储结构及在其上实现线性表的各种基本运算的方法。 循环链表和双链表 时数 2 性质 验证 内容:1、假设在长度大于1的单循环链表中,既无头结点也无头指针。s为指向某个结点的指针,试编写算法删除结点*s的直接前驱结点。 2、已知由单链表表示的线性表中,含有三类字符的数据元素(如:字母、数字和其它字符),设计算法构造三个以循环链表示的线性表,使每一个表中只含同一类的字符,且利用原表中的结点空间作为这三个表的空间。(头结点可以另辟空间) 3、有一双链表,每个结点中除有prior、data和next域外,还有一访问频度域freq,在链表被启用前,其值均初始化为零。每当在链表上进行一次LOCATE(L,x)运算,元素值为x的结点中freq域的值增1,并使此链表中结点保持按freq递减的顺序排列,以便使频繁访问的结点总是靠近表头。设计满足上述要求的LOCATE算法。 要求:熟练掌握线性表的循环链式和双链式链接存储结构及在其上实现线性表的各种基本运算的方法。 栈和队列 时数 2 性质 验证 内容:1、设单链表中存放着n个字符,设计算法,判断该字符串中是否有中心对称关系。例如:xyzzyx、xyzyx都算是中心对称的字符串。 2、设计算法判断一个算术表达式的圆括号是否配对。(提示:对表达式进行扫描,遇‘(’进栈,遇‘)’退掉栈顶的‘(’,表达式被扫描完毕,栈为空) 3、假设以带头结点的循环链表表示队列,并只设一个指针指向队尾,编写相应的置队空、入队和出队算法。 要求:掌握栈和队列的数据结构的特点;熟练掌握在两种存储结构上实现栈和队列的基本运算;学会利用栈和队列解决一些实际问题。 串运算的实现 时数 2 性质 验证 内容:1、若X和Y是用结点大小为1的单链表表示的串,设计算法找出X中第一个不在Y中出现的字符。 2、设计一算法,在顺序串上实现串的比较运算strcmp(S,T)。 3、若S和T是用结点大小为1的单链表存储的两个串,设计算法将S中首次与T匹配的子串逆置。 要求:熟练掌握串的顺序和链接存储结构的实现方法;熟练掌握在两种存储结构上实现串的各种运算。 树的应用 时数 2 性质 验证 内容:1、以二叉链表作存储结构,设计求二叉树高度的算法。 2、一棵n个结点的完全二叉树用向量作存储结构,用非递归算法实现对该二叉树进行前序遍历。 3、以二叉链表作存储结构,编写非递归的前序、中序、后序遍历算法。 要求:熟悉二叉树的各种存储结构的特点及适用范围;掌握建立二叉树的存储结构的方法;熟练掌握二叉树的前序、中序、后序遍历的递归及非递归算法;灵活运用递归的遍历算法实现二叉树的其它各种运算。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值