数据结构(C语言第2版)-----数组,广义表,树,图

简介: 数据结构(C语言第2版)-----数组,广义表,树,图

   任何一个算法的设计取决于选定的数据结构,而算法的实现依赖于采用的存储结构。

   之前线性表的数据元素都是非结构的原子类型,元素的值是不可再分的。下面学习的这两个线性表是很特殊的,其中数据元素本身也可能是一种数据结构。



认识数组和广义表


      数组可以看成是一种特殊的线性表,也就是线性表中的数据元素本身也是一个线性表,数组中的个元素具有统一的类型。其实说白了就是在脑海中想数组中的数据如何在内存中以什么形式的线性表来存储。在C语言中,一个二维数组可以定义为其分量类型为一维数组类型的一维数组类型。


     数组一旦被建立,数组中的维度和维界就不再改变,即数组中的数据元素数目固定,并且数组中每个数据元素都和唯一的一组下标值对应。也就是数组的元素个数和数据元素之间的关系就不能发生变化,所以不会有元素的插入和删除等操作,其基本操作主要是数据元素的读取和更新。


     由于内存空间是一维的结构,而数组元素之间的位置是有规律的,因此用一维连续存储单元存放数组的数据元素就有个次序约定问题。


     广义表简称表,和之前数组是一类的,但是还有点区别,广义表中的不同元素可以有不同的结构,它是一种递归的数据结构。


广义表有三个重要的结论:


  • 层次性:里面的元素可以是子表,子表中的元素也可以是子表,是一个多层次结构


  • 共享性:可以其它表所共享。


  • 递归性:可以是其自身的子表。


 这里面就是说在广义表里面的一个空间中在有一个结构体,里面保存数据的值。之前的内容主要是指针。总感觉广义表这些东西是内存中需要保存的,我们做程序的大体知道就OK,不需要说把里面的细节全部的会。



树和二叉树


  之前了解的栈,队列,数组,广义表等都是线性结构,而树是一种非线性结构,但是一种分层结构,树和二叉树是处理层次模型的典型结构。


  •    树的定义:是n个结点的有限集,在任意一颗非空树中有且只有一个称为根(root)的结点,其余的结点被分为m个互不相交的有限集,其中每个集合本身又是一颗树,称为跟结点的子树。


图示法表示二叉树的一个结论:


  1. 边的数目恰好比结点数目少一个,即e=n-1;


  1. 节点分为根节点,分支结点,叶子结点。


 3.度分为结点的度和树的度,结点的度是指该结点相连的孩子结点的数目,树的度是指树中所有结点的度的最大值。


 4.树是一种分层结构,根结点作为第一层,结点的层次(树深度)是指从根结点开始到该结点的层次数,树的深度是指该树中所有结点的层次的最大值。

 5.森林是m颗互不相交的树的集合。对于树中的每个结点而言,其子树的集合及时森林。


  • 二叉树是一种特殊的有向树,也叫二元位置树。特点是每个结点至多有两棵子树,即二叉树中的每个结点至多有两个孩子结点,且每个孩子结点都有各自的位置关系。


      二叉树定义:二叉树或者可以为空,或者是由一个根结点加上两棵分别称为左子树和右子树的,互不相交的二叉树组成。


  1. 满二叉树:就是除叶子结点外的任何结点均有两个孩子结点,且所有的叶子结点都在同一层上的二叉树。特点是每一层上的结点树是最大的。


  1. 完全二叉树:除去最底层结点后的二叉树是一颗满二叉树,且最底层结点均靠左对其的二叉树。


     算法中处理的事件有两类,一类是客户到达事件,另一类是客户离开事件,前一类事件发生的时刻随客户到来自然形成;后一类事件发生的时刻按先后顺序进行,则由客户事务所需时间和等待所耗的时间而定。


      递归定义的基本项描述了一个或几个递归过程的终结状态,虽然一个有限的递归(无迭代)可以描述一个无限的计算过程,但任何实际应用的递归过程除错误情况外,必定能经过有限层次的递归而终止。所谓终结状态指的是不需要继续递归而可直接求解的状态。


      递归定义的归纳项描述了如何实现从当前状态到终结状态的转换。


      递归设计的实质:当一个复杂的问题可以分解成若干个子问题来处理时,其中某些子问题与原问题有相同的特征属性,则可利用和原问题相同的分析处理方法,反之这些子问题解决了原问题也解决了。

/*
 二叉树的存储
*/
#define VirNode '0';
#define MAX_TREE_SIZE 100;
typedef char ElemType;
typedef ElemType SqBitTree[MAXZ_TREE_SIZE];   //SqBitTree[0]单元存放结点的总数,通常存放构成满二叉树时的结点总数;
//二叉树的层次遍历算法
void leveltree(SqBitTree bt){
    int i,j;
    i=1;
    while(i<=bt[0]){
        for(j=i;j<2*i;j++){
            if(bt[j]==VirNode) printf("*");
            else
                printf("%c",bt[j]);
        }
        printf("\n");
        i=2*i;
    }
}
//二叉树的按层次建立算法
void crebitree(){
    int i,j,m;
    i=1;m=0;
    while(m<n){
        for(j=i;j<2*i;j++){
            scanf("%c",bt+j);
            if(bt[j]!=VirNode)
                m++;
        }
        i=2*i;
    }
    bt[0]=i-1;
}
//交换二叉树中所有结点的左右子树算法
void exchangetree(SqBitTree bt){
    int k=2,i,j;ElemType t;
    while(k<=bt[0]){
        for(i=k,j=2*k-1;i<j;i++,j--){
            t=bt[i];
            bt[i]=bt[j];
            bt[j]=t;
        }
        k=2*k;
    }
}
//统计叶子结点的个数
int countleaf(SqBitTree bt){
    int i,j,n;
    i=1;n=0;
    while(i<=bt[0]/2){
        for(j=i;j<2*i;j++)
            if(bt[j]!=VirNode&&bt[2*j]==VirNode&&bt[2*j+1]==VirNode)
                n++;
            i=2*i;        
    }
    for(j=i;j<2*i;j++)
        if(bt[j]!=VirNode)
            n++;
        return n;
}
//求二叉树的高度
int height(SqBitTree bt){
    int i,j,h;
    i=1;h=0;
    while(i<=bt[0]){
        h++;
        i=2*i;
    }
    return h;
}


二叉树的遍历就是依次访问二叉树中的各个结点,而且每个结点仅被访问一次。遍历的3中方式有,先序遍历,中序遍历,后序遍历。这个主要是看根结点在什么地方,比如第一个,先序,那么就是根左右,中序就是左根右,后序就是左右根;


认识图


     线性表是一种一对一的相邻关系,树是一种一对多的层次关系,图是一种多对多的网状关系,


目录
相关文章
|
26天前
|
算法 数据处理 C语言
C语言中的位运算技巧,涵盖基本概念、应用场景、实用技巧及示例代码,并讨论了位运算的性能优势及其与其他数据结构和算法的结合
本文深入解析了C语言中的位运算技巧,涵盖基本概念、应用场景、实用技巧及示例代码,并讨论了位运算的性能优势及其与其他数据结构和算法的结合,旨在帮助读者掌握这一高效的数据处理方法。
38 1
|
24天前
|
传感器 算法 安全
【C语言】两个数组比较详解
比较两个数组在C语言中有多种实现方法,选择合适的方法取决于具体的应用场景和性能要求。从逐元素比较到使用`memcmp`函数,再到指针优化,每种方法都有其优点和适用范围。在嵌入式系统中,考虑性能和资源限制尤为重要。通过合理选择和优化,可以有效提高程序的运行效率和可靠性。
75 6
|
27天前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
53 5
|
27天前
|
存储 程序员 编译器
C 语言数组与指针的深度剖析与应用
在C语言中,数组与指针是核心概念,二者既独立又紧密相连。数组是在连续内存中存储相同类型数据的结构,而指针则存储内存地址,二者结合可在数据处理、函数传参等方面发挥巨大作用。掌握它们的特性和关系,对于优化程序性能、灵活处理数据结构至关重要。
|
26天前
|
并行计算 算法 测试技术
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
57 1
|
1月前
|
存储 C语言 计算机视觉
在C语言中指针数组和数组指针在动态内存分配中的应用
在C语言中,指针数组和数组指针均可用于动态内存分配。指针数组是数组的每个元素都是指针,可用于指向多个动态分配的内存块;数组指针则指向一个数组,可动态分配和管理大型数据结构。两者结合使用,灵活高效地管理内存。
|
1月前
|
存储 NoSQL 编译器
C 语言中指针数组与数组指针的辨析与应用
在C语言中,指针数组和数组指针是两个容易混淆但用途不同的概念。指针数组是一个数组,其元素是指针类型;而数组指针是指向数组的指针。两者在声明、使用及内存布局上各有特点,正确理解它们有助于更高效地编程。
|
1月前
|
C语言
【数据结构】栈和队列(c语言实现)(附源码)
本文介绍了栈和队列两种数据结构。栈是一种只能在一端进行插入和删除操作的线性表,遵循“先进后出”原则;队列则在一端插入、另一端删除,遵循“先进先出”原则。文章详细讲解了栈和队列的结构定义、方法声明及实现,并提供了完整的代码示例。栈和队列在实际应用中非常广泛,如二叉树的层序遍历和快速排序的非递归实现等。
210 9
|
1月前
|
存储 算法
非递归实现后序遍历时,如何避免栈溢出?
后序遍历的递归实现和非递归实现各有优缺点,在实际应用中需要根据具体的问题需求、二叉树的特点以及性能和空间的限制等因素来选择合适的实现方式。
35 1
|
1月前
|
存储 算法 Java
数据结构的栈
栈作为一种简单而高效的数据结构,在计算机科学和软件开发中有着广泛的应用。通过合理地使用栈,可以有效地解决许多与数据存储和操作相关的问题。

热门文章

最新文章