数据结构实验3

合集下载

数据结构实验报告三

数据结构实验报告三

数据结构实验报告三数据结构实验报告三引言:数据结构是计算机科学中的重要内容之一,它研究的是如何组织和存储数据以便高效地访问和操作。

本实验报告将介绍我在数据结构实验三中的实验过程和结果。

实验目的:本次实验的主要目的是熟悉并掌握树这种数据结构的基本概念和操作方法,包括二叉树、二叉搜索树和平衡二叉树等。

实验内容:1. 实现二叉树的创建和遍历在本次实验中,我首先实现了二叉树的创建和遍历。

通过递归的方式,我能够方便地创建一个二叉树,并且可以使用前序、中序和后序遍历方法对二叉树进行遍历。

这些遍历方法的实现过程相对简单,但能够帮助我们更好地理解树这种数据结构的特点。

2. 实现二叉搜索树的插入和查找接下来,我实现了二叉搜索树的插入和查找操作。

二叉搜索树是一种特殊的二叉树,它的左子树上的节点的值都小于根节点的值,右子树上的节点的值都大于根节点的值。

通过这种特性,我们可以很方便地进行插入和查找操作。

在实现过程中,我使用了递归的方法,通过比较节点的值来确定插入的位置或者进行查找操作。

3. 实现平衡二叉树的插入和查找平衡二叉树是为了解决二叉搜索树在某些情况下可能会退化成链表的问题而提出的。

它通过在插入节点的过程中对树进行旋转操作来保持树的平衡。

在本次实验中,我实现了平衡二叉树的插入和查找操作。

通过对树进行左旋、右旋等操作,我能够保持树的平衡,并且能够在O(log n)的时间复杂度内进行插入和查找操作。

实验结果:通过本次实验,我成功地实现了二叉树、二叉搜索树和平衡二叉树的相关操作。

我编写了测试代码,并对代码进行了测试,结果表明我的实现是正确的。

我能够正确地创建二叉树,并且能够使用前序、中序和后序遍历方法进行遍历。

对于二叉搜索树和平衡二叉树,我能够正确地进行插入和查找操作,并且能够保持树的平衡。

实验总结:通过本次实验,我深入了解了树这种数据结构的特点和操作方法。

二叉树、二叉搜索树和平衡二叉树是树的重要应用,它们在实际开发中有着广泛的应用。

北邮数据结构实验3哈夫曼编码

北邮数据结构实验3哈夫曼编码

数据结构实验报告实验名称:实验3——哈夫曼编码学生姓名:班级:班内序号:学号:日期:2013年11月24日1.实验要求利用二叉树结构实现赫夫曼编/解码器。

基本要求:1、初始化(Init):能够对输入的任意长度的字符串s进行统计,统计每个字符的频度,并建立赫夫曼树2、建立编码表(CreateTable):利用已经建好的赫夫曼树进行编码,并将每个字符的编码输出。

3、编码(Encoding):根据编码表对输入的字符串进行编码,并将编码后的字符串输出。

4、译码(Decoding):利用已经建好的赫夫曼树对编码后的字符串进行译码,并输出译码结果。

5、打印(Print):以直观的方式打印赫夫曼树(选作)6、计算输入的字符串编码前和编码后的长度,并进行分析,讨论赫夫曼编码的压缩效果。

2. 程序分析2.1存储结构:struct HNode{char c;//存字符内容int weight;int lchild, rchild, parent;};struct HCode{char data;char code[100];}; //字符及其编码结构class Huffman{private:HNode* huffTree; //Huffman树HCode* HCodeTable; //Huffman编码表public:Huffman(void);void CreateHTree(int a[], int n); //创建huffman树void CreateCodeTable(char b[], int n); //创建编码表void Encode(char *s, string *d); //编码void Decode(char *s, char *d); //解码void differ(char *,int n);char str2[100];//数组中不同的字符组成的串int dif;//str2[]的大小~Huffman(void);};结点结构为如下所示:三叉树的节点结构:struct HNode//哈夫曼树结点的结构体{ int weight;//结点权值int parent;//双亲指针int lchild;//左孩子指针int rchild;//右孩子指针char data;//字符};示意图为:int weight int parent int lchild int rchild Char c 编码表节点结构:struct HCode//编码表结构体{char data;//字符char code[100];//编码内容};示意图为:基本结构体记录字符和出现次数:struct node{int num;char data;};示意图为:2.关键算法分析(1).初始化:伪代码:1.输入需要编译的文本内容2.将输入的内容保存到数组str1中3.统计出现的字符数目,并且保存到变量count中4.统计出现的不同的字符,存到str2中,将str2的大小存到dif中时间复杂度O(n!)(2).创建哈夫曼树算法伪代码:1.创建一个长度为2*n-1的三叉链表2.将存储字符及其权值的链表中的字符逐个写入三叉链表的前n个结点的data域,并将对应结点的孩子域和双亲域赋为空3.从三叉链表的第n个结点开始,3.1从存储字符及其权值的链表中取出两个权值最小的结点x,y,记录其下标x,y。

数据结构实验三栈和队列的应用

数据结构实验三栈和队列的应用

数据结构实验三栈和队列的应用数据结构实验三:栈和队列的应用在计算机科学领域中,数据结构是组织和存储数据的重要方式,而栈和队列作为两种常见的数据结构,具有广泛的应用场景。

本次实验旨在深入探讨栈和队列在实际问题中的应用,加深对它们特性和操作的理解。

一、栈的应用栈是一种“后进先出”(Last In First Out,LIFO)的数据结构。

这意味着最后进入栈的元素将首先被取出。

1、表达式求值在算术表达式的求值过程中,栈发挥着重要作用。

例如,对于表达式“2 + 3 4”,我们可以通过将操作数压入栈,操作符按照优先级进行处理,实现表达式的正确求值。

当遇到数字时,将其压入操作数栈;遇到操作符时,从操作数栈中弹出相应数量的操作数进行计算,将结果压回操作数栈。

最终,操作数栈中的唯一值就是表达式的结果。

2、括号匹配在程序代码中,检查括号是否匹配是常见的任务。

可以使用栈来实现。

遍历输入的字符串,当遇到左括号时,将其压入栈;当遇到右括号时,弹出栈顶元素,如果弹出的左括号与当前右括号类型匹配,则继续,否则表示括号不匹配。

3、函数调用和递归在程序执行过程中,函数的调用和递归都依赖于栈。

当调用一个函数时,当前的执行环境(包括局部变量、返回地址等)被压入栈中。

当函数返回时,从栈中弹出之前保存的环境,继续之前的执行。

递归函数的执行也是通过栈来实现的,每次递归调用都会在栈中保存当前的状态,直到递归结束,依次从栈中恢复状态。

二、队列的应用队列是一种“先进先出”(First In First Out,FIFO)的数据结构。

1、排队系统在现实生活中的各种排队场景,如银行排队、餐厅叫号等,可以用队列来模拟。

新到达的顾客加入队列尾部,服务完成的顾客从队列头部离开。

通过这种方式,保证了先来的顾客先得到服务,体现了公平性。

2、广度优先搜索在图的遍历算法中,广度优先搜索(BreadthFirst Search,BFS)常使用队列。

从起始节点开始,将其放入队列。

数据结构实验三实验报告

数据结构实验三实验报告

数据结构实验三实验报告数据结构实验三实验报告一、实验目的本次实验的目的是通过实践掌握树的基本操作和应用。

具体来说,我们需要实现一个树的数据结构,并对其进行插入、删除、查找等操作,同时还需要实现树的遍历算法,包括先序、中序和后序遍历。

二、实验原理树是一种非线性的数据结构,由结点和边组成。

树的每个结点都可以有多个子结点,但是每个结点只有一个父结点,除了根结点外。

树的基本操作包括插入、删除和查找。

在本次实验中,我们采用二叉树作为实现树的数据结构。

二叉树是一种特殊的树,每个结点最多只有两个子结点。

根据二叉树的特点,我们可以使用递归的方式实现树的插入、删除和查找操作。

三、实验过程1. 实现树的数据结构首先,我们需要定义树的结点类,包括结点值、左子结点和右子结点。

然后,我们可以定义树的类,包括根结点和相应的操作方法,如插入、删除和查找。

2. 实现插入操作插入操作是将一个新的结点添加到树中的过程。

我们可以通过递归的方式实现插入操作。

具体来说,如果要插入的值小于当前结点的值,则将其插入到左子树中;如果要插入的值大于当前结点的值,则将其插入到右子树中。

如果当前结点为空,则将新的结点作为当前结点。

3. 实现删除操作删除操作是将指定的结点从树中移除的过程。

我们同样可以通过递归的方式实现删除操作。

具体来说,如果要删除的值小于当前结点的值,则在左子树中继续查找;如果要删除的值大于当前结点的值,则在右子树中继续查找。

如果要删除的值等于当前结点的值,则有三种情况:- 当前结点没有子结点:直接将当前结点置为空。

- 当前结点只有一个子结点:将当前结点的子结点替代当前结点。

- 当前结点有两个子结点:找到当前结点右子树中的最小值,将其替代当前结点,并在右子树中删除该最小值。

4. 实现查找操作查找操作是在树中寻找指定值的过程。

同样可以通过递归的方式实现查找操作。

具体来说,如果要查找的值小于当前结点的值,则在左子树中继续查找;如果要查找的值大于当前结点的值,则在右子树中继续查找。

数据结构实验报告三

数据结构实验报告三
L->r[j+1]=L->r[j];
L->r[j+1]=L->r[0];
}
}
main()
{
SortList *L;
int i;
L->r[0].key=0;
L->r[1].key=49;
L->r[2].key=38;
L->r[3].key=65;
L->r[4].key=97;
L->r[5].key=76;
}SortList;
void InsertSort(SortList *L)
{
int i,j;
for(i=2;i<=L->length;i++)
if(L->r[i].key<L->r[i-1].key){
L->r[0]=L->r[i];
for(j=i-1;L->r[0].key<L->r[j].key;j--)
L->r[6].key=13;
L->r[7].key=27;
L->r[8].key=52;
L->length=8;
SelectSort(L);
printf("\n\n");
for(i=1;i<=L->length;i++)
printf("%d\n",L->r[i].key);
}
附2:原程序
#define SORT_LIST_MAXSIZE 20
typedef int KeyType;
typedef int InfoType;
typedef struct{

国家开放大学《数据结构》课程实验报告(实验3 ——栈、队列、递归设计)参考答案

国家开放大学《数据结构》课程实验报告(实验3 ——栈、队列、递归设计)参考答案
{
x=Pop(s); /*出栈*/
printf("%d ",x);
InQueue(sq,x); /*入队*/
}
printf("\n");
printf("(10)栈为%s,",(StackEmpty(s)?"空":"非空"));
printf("队列为%s\n",(QueueEmpty(sq)?"空":"非空"));
ElemType Pop(SeqStack *s); /*出栈*/
ElemType GetTop(SeqStack *s); /*取栈顶元素*/
void DispStack(SeqStack *s); /*依次输出从栈顶到栈底的元素*/
void DispBottom(SeqStack *s); /*输出栈底元素*/
} SeqQueue; /*定义顺序队列*/
void InitStack(SeqStack *s); /*初始化栈*/
int StackEmpty(SeqStack *s); /*判栈空*/
int StackFull(SeqStack *s); /*判栈满*/
void Push(SeqStack *s,ElemType x); /*进栈*/
sq=(SeqQueue *)malloc(sizeof(SeqQueue));
InitQueue(sq);
printf("(8)队列为%s\n",(QueueEmpty(sq)?"空":"非空"));
printf("(9)出栈/入队的元素依次为:");

数据结构实验报告3

数据结构实验报告3

数据结构实验报告3数据结构实验报告3引言:数据结构是计算机科学中的一个重要概念,它涉及到数据的组织、存储和管理。

在本次实验中,我们将探索一些常见的数据结构,并通过实验来验证它们的性能和效果。

一、线性表线性表是最基本的数据结构之一,它是一种由一组数据元素组成的有序序列。

在本次实验中,我们使用了顺序表和链表来实现线性表。

顺序表是一种连续存储的数据结构,它可以通过下标来访问元素。

我们通过实验比较了顺序表的插入和删除操作的时间复杂度,发现在插入和删除元素较多的情况下,顺序表的性能较差。

链表是一种非连续存储的数据结构,它通过指针来连接各个元素。

我们通过实验比较了链表的插入和删除操作的时间复杂度,发现链表在插入和删除元素时具有较好的性能。

二、栈栈是一种特殊的线性表,它只允许在表的一端进行插入和删除操作。

在本次实验中,我们实现了栈的顺序存储和链式存储两种方式。

顺序存储的栈使用数组来存储元素,我们通过实验比较了顺序存储栈和链式存储栈的性能差异。

结果表明,在元素数量较少的情况下,顺序存储栈具有较好的性能,而在元素数量较多时,链式存储栈更具优势。

三、队列队列是一种特殊的线性表,它只允许在表的一端进行插入操作,在另一端进行删除操作。

在本次实验中,我们实现了队列的顺序存储和链式存储两种方式。

顺序存储的队列使用数组来存储元素,我们通过实验比较了顺序存储队列和链式存储队列的性能差异。

结果表明,顺序存储队列在插入和删除元素时具有较好的性能,而链式存储队列在元素数量较多时更具优势。

四、树树是一种非线性的数据结构,它由一组称为节点的元素组成,通过节点之间的连接来表示数据之间的层次关系。

在本次实验中,我们实现了二叉树和二叉搜索树。

二叉树是一种每个节点最多有两个子节点的树结构,我们通过实验验证了二叉树的遍历算法的正确性。

二叉搜索树是一种特殊的二叉树,它的左子树的所有节点都小于根节点,右子树的所有节点都大于根节点。

我们通过实验比较了二叉搜索树的插入和查找操作的时间复杂度,发现二叉搜索树在查找元素时具有较好的性能。

北京理工大学数据结构实验报告3

北京理工大学数据结构实验报告3

《数据结构与算法统计》实验报告——实验三学院:班级:学号:姓名:一、实验目的1 熟悉VC环境,学会使用C++解决关于二叉树的问题。

2 在上机、调试的过程中,加强对二叉树的理解和运用。

3 锻炼动手编程和独立思考的能力。

二、实验内容遍历二叉树。

请输入一棵二叉树的扩展的前序序列,经过处理后生成一棵二叉树,然后对于该二叉树输出前序、中序和后序遍历序列。

三、程序设计1、概要设计为实现上述程序功能,首先需要二叉树的抽象数据结构。

⑴二叉树的抽象数据类型定义为:ADT BinaryTree {数据对象D:D是具有相同特性的数据元素的集合。

数据关系R:若D=Φ,则R=Φ,称BinaryTree为空二叉树;若D≠Φ,则R={H},H是如下二元关系;(1)在D中存在惟一的称为根的数据元素root,它在关系H下无前驱;(2)若D-{root}≠Φ,则存在D-{root}={D1,Dr},且D1∩Dr =Φ;(3)若D1≠Φ,则D1中存在惟一的元素x1,<root,x1>∈H,且存在D1上的关系H1 ⊆H;若Dr≠Φ,则Dr中存在惟一的元素xr,<root,xr>∈H,且存在上的关系Hr ⊆H;H={<root,x1>,<root,xr>,H1,Hr};(4)(D1,{H1})是一棵符合本定义的二叉树,称为根的左子树;(Dr,{Hr})是一棵符合本定义的二叉树,称为根的右子树。

基本操作:CreatBiTree(BiTree &T)操作结果:按先序次序建立二叉链表表示的二叉树TPreOrderTraverse(BiTree T,int (*visit)(char e))初始条件:二叉树T已经存在,visit是对结点操作的应用函数操作结果:先序遍历二叉树T ,对每个结点调用visit函数仅一次;一旦visit()失败,则操作失败。

InOrderTraverse(BiTree T,int (*visit)(char e))初始条件:二叉树T已经存在,visit是对结点操作的应用函数操作结果:中序遍历二叉树T ,对每个结点调用visit函数仅一次;一旦visit()失败,则操作失败。

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

《数据结构与算法》实验报告实验序号:3 实验项目名称:链式表的操作2、改写以上程序,实现功能如下:(1〕编写一个删除链表中值为x的结点的直接前趋结点的算法,假设有多个值为x的结点,那么删除第一个x的直接前趋结点。

(2〕改写CreatListR1函数,使得链表创立时为非递减有序的单链表。

(3〕在算法(2〕生成的非递减有序的单链表中,编写一个算法,删除单链表中值一样的多余结点。

(4〕写一个对单循环链表进展逆序输出〔打印每个结点的值〕的算法。

四、实验结果与数据处理一.实验结果如图1所示:图1二.〔1〕实验结果如图2所示:图2 〔2〕实验结果如图3所示:图3 〔3〕实验结果如图4所示:图4(4)实验结果如图5所示:图5五、分析与讨论感觉实验3比之前的实验一、二难度更大,只能浏览同学的,有疑问便问同学,这样勉强理解。

附源程序清单:一.#include"stdio.h"#include"stdlib.h"typedef struct node //定义结点{int data; //结点的数据域为整型struct node *next; //结点的指针域}ListNode;typedef ListNode * LinkList; // 自定义LinkList单链表类型LinkList CreatListR1(); //函数,用尾插入法建立带头结点的单链表void printlist(LinkList head); //函数,打印链表中的所有值ListNode *LocateNode(LinkList head, int key); //函数,按值查找结点void DeleteList(LinkList head,int key); //函数,删除指定值的结点void DeleteAll(LinkList head);void main(){int num;char ch;LinkList head;head=CreatListR1();printf("List:\n");printlist(head);printf(" Delete node (y/n):"); //输入"y"或"n"去选择是否删除结点getchar();scanf("%c",&ch);if(ch=='y'||ch=='Y'){printf("Please input Delete_data:");scanf("%d",&num); //输入要删除的数DeleteList(head,num); //删除printlist(head); //打印}DeleteAll(head); //删除所有结点,释放存}//==========用尾插入法建立带头结点的单链表===========LinkList CreatListR1(void){int n,i,count;LinkList head=(LinkList)malloc(sizeof(ListNode));ListNode *s, *r;//s用来指向新生成的节点。

r始终指向L的终端节点。

r=head;r->next=NULL;printf("请输入链表节点数:");scanf("%d",&n);printf("输入节点值:");for ( i = 0; i < n; i++) {s = (LinkList)malloc(sizeof(ListNode));//s指向新申请的节点scanf("%d",&count);s->data = count; //用新节点的数据域来承受ir->next = s; //用r来接纳新节点r = s; //r指向终端节点}r->next = NULL;return head; //返回头指针 return head; //返回头指针}void printlist(LinkList head){ListNode *p=head->next; //从开场结点打印while(p){printf("%d, ",p->data);p=p->next;}printf("\n");}//==========按值查找结点,找到那么返回该结点的位置,否那么返回NULL========== ListNode *LocateNode(LinkList head, int key){ListNode *p=head->next; //从开场结点比拟while(p && p->data!=key) //直到p为NULL或p-> data为key止p=p->next; //扫描下一个结点return p; //假设p=NULL那么查找失败,否那么p指向找到的值为key的结点}//==========删除带头结点的单链表中的指定结点=======void DeleteList(LinkList head,int key){ListNode *p,*r,*q=head;p=LocateNode(head,key); //按key值查找结点的if(p==NULL ) { //假设没有找到结点,退出printf("position error");exit(0);}while(q->next!=p) //p为要删除的结点,q为p的前结点q=q->next;r=q->next;q->next=r->next;free(r); //释放结点}//==========删除所有结点,释放空间===========void DeleteAll(LinkList head){ListNode *p=head,*r;while(p->next){r=p->next;free(p);p=r;}free(p);}二.〔1〕#include"stdio.h"#include"stdlib.h"typedef struct node //定义结点{int data; //结点的数据域为整型struct node *next; //结点的指针域}ListNode;typedef ListNode * LinkList; // 自定义LinkList单链表类型LinkList CreatListR1(); //函数,用尾插入法建立带头结点的单链表void printlist(LinkList head);ListNode *LocateNode(LinkList head, int key); //函数,按值查找前结点void DeleteList(LinkList head,int key); //函数,删除指定值的结点void DeleteAll(LinkList head);void main(){int num;char ch;LinkList head;head=CreatListR1();printf("List:\n");printlist(head);printf(" 是否删除链表中值为x的结点的直接前趋结点(y/n):"); //输入"y"或"n"去选择是否删除结点getchar();scanf("%c",&ch);if(ch=='y'||ch=='Y'){printf("Please input Delete_data:");scanf("%d",&num); //输入要删除的字符串DeleteList(head,num);printlist(head);}DeleteAll(head); //删除所有结点,释放存}//==========用尾插入法建立带头结点的单链表===========LinkList CreatListR1(void){int n,i,count;LinkList head=(LinkList)malloc(sizeof(ListNode));ListNode *s, *r;//s用来指向新生成的节点。

r始终指向L的终端节点。

r=head;r->next=NULL;printf("请输入链表节点数:");scanf("%d",&n);printf("输入节点值:");for ( i = 0; i < n; i++) {s = (LinkList)malloc(sizeof(ListNode));//s指向新申请的节点scanf("%d",&count);s->data = count; //用新节点的数据域来承受ir->next = s; //用r来接纳新节点r = s; //r指向终端节点}r->next = NULL;return head; //返回头指针 return head; //返回头指针}void printlist(LinkList head){ListNode *p=head->next; //从开场结点打印while(p){printf("%d, ",p->data);p=p->next;}printf("\n");}//==========//按值查找结点,找到返回该结点的直接前驱结点位置,否那么返回NULL==========ListNode *LocateNode(LinkList head, int key){ListNode *p=head->next;ListNode *x=head->next;//从开场结点比拟while(p && p->data!=key)//直到p为NULL或p-> data为key止{x=p; // x为P的前一个节点;p=p->next;}//扫描下一个结点if( p->data!=key){x=NULL;}return x; //假设p=NULL那么查找失败,否那么p指向找到的值为key的结点}//==========删除带头结点的单链表中的指定结点=======void DeleteList(LinkList head,int key){ListNode *p,*r,*q=head;p=LocateNode(head,key); //按key值查找结点的if(p==NULL ) { //假设没有找到结点,退出printf("position error");exit(0);}while(q->next!=p) //p为要删除的结点,q为p的前结点q=q->next;r=q->next;q->next=r->next;free(r); //释放结点}//==========删除所有结点,释放空间===========void DeleteAll(LinkList head){ListNode *p=head,*r;while(p->next){r=p->next;free(p);p=r;}free(p);}〔2〕#include"stdio.h"#include"stdlib.h"typedef struct node //定义结点{int data; //结点的数据域为整型struct node *next; //结点的指针域}ListNode;typedef ListNode * LinkList; // 自定义LinkList单链表类型LinkList CreatListR1(); //函数,用尾插入法建立带头结点的单链表void printlist(LinkList head);void DeleteAll(LinkList head);void main(){int num;char ch;LinkList head;head=CreatListR1();printf("List:\n");printlist(head);DeleteAll(head); //删除所有结点,释放存}//==========用尾插入法建立带头结点的单链表===========LinkList CreatListR1(void){int n,i,count,change,j;LinkList head=(LinkList)malloc(sizeof(ListNode));ListNode *s, *r,*q;//s用来指向新生成的节点。

相关文档
最新文档