【精选】数据结构复习_数据结构的形式化定义及两个构成要素的含义-程序员宅基地

技术标签: 算法  c  c语言  链表  数据结构  

复习题

一、简述题
  1. 说明在带头结点单链表L中以下三个概念的关系:头指针,头结点,首元素结点。

头指针:指向链表的第一个结点的指针。

首元结点:链表存放数据的第一个结点。

头结点:链表的第一个结点,但是其数据域不含有数据,指针域内指针指向首元结点。

  1. 简述在图的遍历中,设置访问标志数组的作用。

保证图中的各顶点在遍历过程中仅访问一次

  1. 说明具有n个结点的二叉树Bt,若采用二叉链表存储表示法,其空链域的数目,并写出求解过程。

2n-(n-1)=n+1

  1. 简述线性表的链式存储结构的优缺点

优点:插入、删除运算方便
缺点:占用额外的存储空间存储元素之间的关系,存储密度降低
不能随机存取元素

  1. 简述在一般的顺序队列中的“ 假溢出 ” 问题及解决方法。

随着队头出队慢慢地就会空出一个个存储单元,但是队尾一直再进,最后就是存储空间根本没用满,队列就满了

一种是另设一个布尔变量来判断;

第二种是少用一个元素空间,入队时先测试((rear+1)%m = front)? 满:空;

第三种就是用一个计数器记录队列中的元素的总数。

  1. 设有1000个无序元素,仅要求找出前10个最小元素,在下列排序方法中(归并排序、基数排序、快速排序、堆排序、插入排序)哪一种方法最好,为什么?

用堆排序或锦标赛排序最合适,因为不必等全部元素排完就能得到所需结果,时间效率为O(nlog2n)

  1. 请写出数据结构的形式化定义,分别说明两个构成要素的含义。

数据结构是一个二元组Data_Structures=(D, S),其中,D是数据元素的有限集,S是D上关系的有限集。

  1. 使用折半查找的两个前提条件是什么?

1)采用物理线性结构存储;

2)数据必须有序。

  1. 排序算法的稳定性。 举例说明某个排序算法是不稳定的。

假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变。


线性表

1.顺序表L删除所有值为x的元素,时间复杂度O(n),空间复杂度O(1)
void delx(SqlList* L,ElemType x){
   
    
    i=0,j=0;
    while(i<L->last){
   
    
        if(L->elem[i]!=x){
   
    
            L->elem[j]=L->elem[i];
            i++,j++;
        }else{
   
    
            i++;
        }
    }
    L->last=j-1;
}
2.带头结点单链表就地逆置
void ReserveList(LinkList L){
   
    
    p=L->next;
    L->next=NULL;
    while(p){
   
    
        q=p->next;	//保留当前处理节点的下一个节点
        p->next=L->next;
        L-next=p;
        p=q;
    }
}
3.带头结点单链表L,以表中第一个元素值为标准,将表中所有值小于第一个元素放在第一个元素之前,大于放在之后
void changeList(LinkList L){
   
    
    if(L->next==NULL){
   
    
        return;
    }
    p1=L->next;
    pre=p1;	//pre始终指向正在处理元素的前一个位置
    p=p1->next;		//p为当前处理节点
    while(p){
   
    
        q=p->next;	//保存当前处理节点的下一个节点
        if(p->data>=p1->data){
   
    
            pre=p;
            p=q;
        }else{
   
    
            pre->next=p->next;
            p->next=L->next;
            L->next=p;
            p=q;
        }
    }
}

栈与队列

1.括号匹配算法
void BracketMatch(char* str){
   
    	//str为输入字符
    Stack S;
    int i;char ch;
    InitStack(&S);
    for(i=0;str[i]!='\0';i++){
   
    
        switch(str[i]){
   
    
            case '(':
            case '[':
            case '{':
            	Push($S,str[i]);
                break;
            case ')':
            case ']':
            case '}':
            	if(isEmpty(S)){
   
    
                    printf("右括号多余");
                }else{
   
    
                    GetTop(S,&ch);
                    if(Match(ch,str[i])){
   
    
                        Pop(&S,&ch);
                    }else{
   
    
                        printf("左右括号不同类");
                    }
                }
                break;
        }
    }
    if(IsEmpty(S)){
   
    
        printf("括号匹配");
    }else{
   
    
        printf("左括号多余");
    }
}
2.无括号算术表达式处理
//读入一个简单表达式计算值,OPTR为运算符栈,OVS为运算数栈
int ExpEvaluation(){
   
    
    InitStack($OPTR);
    InitStack(&OVS);
    Push($OPTR,'#');
    ch=getchar();
    while(ch!='#'||GetTop(OPTR)!='#'){
   
    
        if(!In(ch,OPSet)){
   
    	//不是操作符 是操作数
            n=GetNumber(ch);
            Push(&OVS,n);
            ch=getchar();
        }else{
   
    
            switch(Compare(ch,GetTop(&OPTR))){
   
    
                case '>':Push(&OPTR,ch);ch=getchar();break;
                case '=':
                case '<':Pop(&OPTR,&op);Pop(&OVS,&b);
                    	 Pop(&OVS,&a);v=Excute(a,op,b);
                    	 Push(&OVS,v);break;
            }
        }
    }
    v=GetTop(&OVS);
    return v;
}
3.汉诺塔递归算法
//将X上从上到下编号1至n,直径由小到大叠放的n个圆盘,按规则借助Y移动到Z上
void hannoi(int n,char X,char Y,cahr Z){
   
    
    if(n==1){
   
    
        move(X,1,Z);
    }else{
   
    
        hannoi(n-1,X,Z,Y);
        move(X,n,Z);
        honnoi(n-1,Y,X,Z);
    }
}

4.打印杨辉三角形前n行元素
void YangHuiTriangle(){
   
    
    SeqQueue Q;
    InitQueue(&Q);
    EnterQueue(&Q,1);		//第1行元素入队
    for(n=2;n<=N;n++){
   
    
        EnterQueue(&Q,1);	//第n行第一个元素入队
        for(i=1;i<=n-2;i++){
   
    //利用n-1行元素产生第n行中间n-2个元素
            DeleteQueue(&Q,&tmp);
            printf(tmp);
            GetHead(Q,&x);
            tmp+=x;
            EnterQueue(&Q,tmp);
        }
        DeleteQueue(&Q,&x);
        printf(x);
        EnterQueue(&Q,1);	//第n行最后一个元素入队
    }
    while(!IsEmpty(Q)){
   
    
        DeleteQueue(&Q,&x);
        printf(x);
    }
}

树与二叉树

一、二叉树的遍历与线索化
1.输出二叉树中的节点
void PreOrder(BiTree root){
   
    
    if(root!=NULL){
   
    
        printf(root->data);
        PreOrder(root->LChild);
        PreOrder(root->RChild);
    }
}
2.输出二叉树中的叶子节点
void PreOrder(BiTree root){
   
    
    if(root!=NULL){
   
    
        if(root->LChild==NULL&&root->RChild==NULL){
   
    
            printf(root->data);
        }
        PreOrder(root->LChild);
        PreOrder(root->RChild);
    }
}
3.统计叶子节点的数目

方法一:后序遍历实现

//leafCount为保存叶子节点数目的全局变量 初始值为0
void leaf(BiTree root){
   
    
    if(root!=NULL){
   
    
        leaf(root->LChild);
        leaf(root->RChild);
        if(root->LChild==NULL&&root->RChild==NULL){
   
    
            leafCount++;
        }
    }
}

方法二:分治算法

void leaf(BiTree root){
   
    
    int leafCount;
    if(root==NULL){
   
    
        leafCount=0;
    }else if(root->LChild==NULL&&root->RChild==NULL){
   
    
        leafCount=1;
    }else{
   
    
        leafCount=leaf(root->LChild)+leaf(root->RChild);
    }
    return leafCount;
}
4.拓展先序序列创建二叉树
void CreateBiTree(BiTree* bt){
   
    
    char ch;
    ch=getchar();
    if(ch=='.'){
   
    
        *bt=NULL;
    }else{
   
    
        *bt=(BiTree)malloc(sizeof(BiTNode));
        (*bt)->data=ch;
        CreateBiTree(&((*bt)->LChild));
        CreateBiTree(&((*bt)->RChild));
    }
}
5.求二叉树高度

分治法

int PostTreeDepth(BiTree bt){
   
    
    int hr,hl,max;
    if(bt!=NULL){
   
    
        hl=PostTreeDepth(bt->LChild);	//求左子树的深度
        hr=PostTreeDepth(bt->RChild);	//求右子树的深度
        max=hr>hl?hr:hl;
        return max+1;	//加树根的高度
    }else{
   
    
        return 0;
    }
}

先序遍历实现

//depth为全局变量 为当前求得的最大层次
void PreTreeDepth(BiTree bt,int h){
   
    
    if(bt!=NULL){
   
    
        if(h>depth){
   
    
            depth=h;
        }
        PreTreeDepth(bt->LChild,h+1);
        PreTreeDepth(bt->RChild,h+1);
    }
}
6.按横向树形显示二叉树
//二叉树的横向显示是竖向显示的逆时针90度旋转,分析可知输出的节点序列正好为逆中序顺序
void PrintTree(BiTree bt,int nLayer){
   
    
    if(bt==NULL){
   
    
        return;
    }
    PrintTree(bt->RChild,nLayer+1);
    for(i=0;i<nLayer;i++){
   
    
        printf(" ");
    }
    printf(bt->data);
    PrintTree(bt->LChild,nLayer+1);
}
二、基于栈的递归消除
1.中序遍历二叉树的非递归算法
void InOrder(BiTree root){
   
    
    InitStack(&S);
    p=root;
    while(p!=NULL||!IsEmpty(S)){
   
    
        if(p!=NULL){
   
    
            Push(&S,p);
            p=p->LChild;
        }else
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/apple_54886810/article/details/123219622

智能推荐

HTTP4.5.9工具类/时间工具类_如何将httputil工具类中的时间设置为北京时间-程序员宅基地

文章浏览阅读150次。package com.xinyunfu.utils;import org.apache.http.HttpEntity;import org.apache.http.NameValuePair;import org.apache.http.client.ClientProtocolException;import org.apache.http.client.config.Reques..._如何将httputil工具类中的时间设置为北京时间

Flume系列之:查看flume生成的gz文件中的数据_查看hdfs中/tmp/flume目录下生成的内容_最笨的羊羊的博客-程序员宅基地

文章浏览阅读803次。Flume系列之:查看flume生成的gz文件中的数据一、flume落到hdfs文件格式二、查看hdfs上生成的文件三、查看文件中的数据一、flume落到hdfs文件格式sinks.sink1.hdfs.codeC sinks.sink1.hdfs.codeC = gzip文件压缩格式,包括:gzip,bzip2, lzo, lzop, snappy二、查看hdfs上生成的文件/optics/raw/kafka/debezium-prod-optics_prod_1h/optics_prod/_查看hdfs中/tmp/flume目录下生成的内容

让公式在网页传播——mathJAX-程序员宅基地

文章浏览阅读113次。让公式在网页传播——mathJAX对于学生党而言,写公式最好的工具是LaTeX,但LaTeX把公式展示到互联网上就有些困难,而使用截图又不太雅观。幸运的是,mathJAX引擎可以在浏览器中解析渲染数学符号公式,而不需要图片导入mathJAX官方文档在这里,参考网页mathJAX本质是一段JavaScript脚本,可以本地引用,也可以使用cdn,这里采用引用国内的bootcss cdn的方式...

基于S3C2410的触摸屏驱动程序设计-程序员宅基地

文章浏览阅读1.9k次。基于S3C2410的触摸屏驱动程序设计 作者:沈阳农业大学 关键词: ADS7843 S3C2410 触摸屏 嵌入式Linux 消费电子 触摸屏 消费电子 摘要: 本文介绍了基于三星S3C2410X微处理器,采用SPI接口与ADS7843触摸屏">触摸屏控制器芯片完成触摸屏">触摸屏模块的设计。具体包括在嵌入

解析JSON数据系列1:在网页上显示Json数据-程序员宅基地

文章浏览阅读4.9k次。Json的全称:JavaScriptObjectNotationJson的两种构建结构:“名称/值”对的集合、值的有序列表。移动客户端(android和iphone)接收返回的数据和平台无关,平台可以是Java、.net或者php。移动客户端请求服务器端,一般是采用Json这种轻量级的形式。JSON的数据格式:JSON对象是一个无序的“‘名称/值’对”集

LOJ 「SDOI2017」新生舞会(二分 + 分数规划+ 费用流)-程序员宅基地

文章浏览阅读475次。点击打开链接看到这题,首先看到,一对一,那么感觉是二分图?看了看数据,挺像的。然后看到,原来是要一个C值最大。很典型的分数规划。我们转移一下就可以得到(a_1 - b_1 * c) + (a_2 - b_2 * c) + (a_3 - b_3 * c) + (a_4 - b_4 * c)....... = 0所以我们只要去枚举c,然后不断让上式向着零趋近,最后输出即可。当然,我

随便推点

Springboot连接数据库url详解_springboot databaseurl-程序员宅基地

文章浏览阅读1.6k次。Springboot连接数据库url详解_springboot databaseurl

图像边缘检测之Prewitt算子-程序员宅基地

文章浏览阅读1.8w次,点赞7次,收藏89次。Prewitt 算子1. 原理Prewitt算子是一种图像边缘检测的微分算子,其原理是利用特定区域内像素灰度值产生的差分实现边缘检测。由于Prewitt算子采用 3x3 模板对区域内的像素值进行计算,而Robert算子的模板为 2x2,故Prewitt算子的边缘检测结果在水平方向和垂直方向均比Robert算子更加明显。Prewitt算子适合用来识别噪声较多、灰度渐变的图像,其计算公式如下所示:例如,下面给出Prewitt算子的模板,在像素点P5处 x 和 y 方向上的梯度大小 g_x 和 g_y 分_prewitt算子

redis桌面管理工具 redis-desktop-manager使用指南-程序员宅基地

文章浏览阅读4.5k次。概要:一款好用的Redis桌面管理工具,支持命令控制台操作,以及常用,查询key,rename,delete等操作。下载软件,请点击下面链接,进入下载页,选择对应版本:https://redisdesktop.com/download redisdesktop桌面管理工具操作使用如下图: 一、新建连接输入redis主机host,端口号

Docker备份迁移,稳了!-程序员宅基地

文章浏览阅读754次。点击蓝色“程序员的时光”关注我,标注“星标”,及时阅读最新技术文章写在前面:小伙伴儿们,大家好!今天来聊一聊Docker迁移备份以及DockerFile相关的知识;下一篇就讲Dock..._docker mysql 维护 迁移 备份

Sprite的一些有趣的现象_sprite换行显示-程序员宅基地

文章浏览阅读912次。sprite是经常用到的显示对象,它有一些十分有趣的特性(也十分的坑爹)。 1.当sprite里面没有任何子显示对象,也没用graphics画任何的图形时,这时如果给sprite的width和height赋值的话,scaleX和scaleY将会变成0,之后再往sprite添加任何显示对象或者用graphics画图都不会显示。如果先添加显示对象,则sprite的width/height就是有里面_sprite换行显示

USB转串口 FT232/PL2303/CH340 驱动以及使用体会_ft232pl 驱动-程序员宅基地

文章浏览阅读1.2k次。emouse原创文章,转载请注明出处http://www.cnblogs.com/emouse/现在笔记本上很少带有串口了,而串口又是做电子设计必备的通讯接口之一,好在USB转串口比较方便,市面上常用的USB转串口芯片有很多,最常见的有FT232、PL2303、CH340三种,这三种我分别说一下,同时整理一下他们的驱动程序,网上找驱动程序的很多,也有很多人发布,找驱动程序当然要去官网找了,这样_ft232pl 驱动

推荐文章

热门文章

相关标签