六、C语言数据结构和算法

(1)数据结构,顾名思义,数据的结构,而如何将数据组合成一种结构了,C语言里用到了struct结构体类型、union联合体类型、enum枚举类型这三种。

 

struct结构体类型,顾名思义,是一种结构,一种由基本数据类型(int、char、double、float等等)组合而成的一个整体,至于如何组合,很简单。

如:

struct 结构体名字

{

         int  mA;

         int  mKK;

         float  m_Float;

};//不要忘记末尾加分号

结构体名字就是变量名,遵循命名规则,这样就定义了一个结构体类型!注意,是定义了一种类型!这种类型和基本数据类型是没有任何区别的,都是数据类型!都是可以用来定义变量的!

结构体类型定义变量的方式:

【struct 结构体名字 变量名;】

这样就定义了一个某某结构体的变量了,若是如此:

【struct 结构体名字* 变量名;】

这样就定义了一个某某结构体变量的指针了。

 

注意:C语言的结构体类型是【struct 结构体名字】,记住,这是两个单词组合起来作为一个类型名称使用的!这个的一个整体就等价于整型的int这个符号。以后不论任何时候使用到结构体类型,都必须是【struct 结构体名字】这种方式。

如:某某结构体指针类型【struct 结构体名字*】,这里多了个*解引用运算符,用来表示指针。

 

如:

struct myStructName

{

         int  mA;

         int  mKK;

         float  m_Float;

         struct myStructName*  next;

};//不要忘记末尾加分号

这里在myStructName结构体中定义一个myStructName结构体的指针,但注意,这里不能定义myStructName结构体的变量,因为myStructName结构体其实还没定义,只是被声明了,只有在分号结束后才定义了myStructName结构体。

而且,反证法,若是myStructName结构体内部定义了一个myStructName的结构体变量,显然sizeof(struct myStructName)时候,这里的sizeof是在编译时候就获得结果大小的函数,sizeof去获取myStructName结构体的大小,但是myStructName结构体的里面还有myStructName结构体大小,怎么办?死循环呗!挂掉了!

而若是myStructName结构体里面定义myStructName结构体指针,不论任何指针都只有32位的,所以sizeof是有效的。

 

如,定义一个链表,显然需要两个结构体,链表描述需要一个,链表节点需要一个:

struct myListNode

{

         struct myListNode* next;        //指向下一个节点的指针

         struct myListNode* prev;        //指向前一个节点的指针

         int mData;        //节点存储的数据

};

struct myList

{

         struct myListNode*  mHead;         //指向链表头部指针

         struct myListNode*  mTail;            //指向链表尾部指针

         int  m_size;    //链表的大小

};

这两个结构体定义就能够组合成一个链表,若是加上一些操作链表的函数,就成为了一个数据结构。简单吧!

注:链表不可能是连续分配的内存,所以链表使用的内存必须是malloc分配的堆内存,也就是由程序员自己管理,只要能够索引到对应的内存指针,就能获取对应的数据。

注:链表,生动地来说,就像无数条链子链接起来的一块块内存,可能这块内存在这里,可能那块内存在那里,内存位置是不确定的,但所有的内存必然有且至少有一个指针指向它!而这些内存就能够存放数据了。

 

(2)union联合体

联合体,顾名思义是联合起来的一个整体,如何联合起来呢?就是内存空间联合起来!也就是一段内存空间,可以存放联合体中所定义的任何类型数据。

注:联合体的声明和定义和结构体的声明定义是一样的,但是对联合体的解释是不同的。

如:

union 联合体名字

{

         int  mA;

         short  mB;

         char  mC;

         double mD;

};//不要忘记分号

这个联合体的内存只会分配其成员中,占用内存最大的内存数量的内存空间!这里是double占用空间最大,有8个字节,所以这个联合体只占8个字节!

而且联合体的值,每一次对其成员进行赋值,都会改变所有成员的值,如:

【union 联合体名字 myUnion; myUnion.mA = 10; myUnion.mB = 20;】

这里在第一次赋值为10之后,不论是mB、mC或mD都是10,直到第二次赋值为20,那么不论是mA、mB、mC或mD都是20。也就是同一时间,联合体只能存储一个值!

 

 

(3)enum枚举类型

枚举类型,顾名思义,枚举,就是所有值都列举出来!所以其声明定义如下:

enum

{

         ENUM_Name1,

         ENUM_Name2,

         ENUM_Name3,

};

枚举类型里的成员必定是一个名字,且这个名字代表着某个值,若是没有被赋值,就会默认赋值给前一个名字数值的加一,如第一个ENUM_Name1没有赋值,默认值为0,ENUM_Name2就是“0+1”,ENUM_Name3就是“1+1”,这里的ENUM_Name2和ENUM_Name3并不是简单的1和2,其值和名字是作为一个唯一标识,作为枚举的一个成员。

这里的值可以重复的,如:

enum

{

         ENUM_Name1 = 1,

         ENUM_Name2,

         ENUM_Name3 = 2,

};

很显然,ENUM_Name2的值就是“1+1”,看起来字面上是2,且和ENUM_Name3重复,但真正的值并不是2,而是“1+1”。

注:枚举类型里的成员都是明确规定的值,这些值不管字面上表示如何,都绝对不会是相同的。而且枚举类型的成员的类型是独有的,和其他基本数据类型不同。

 

 

(4)算法,顾名思义,是计算的方法,计算的方式方案,怎么计算就会有怎么样的方法,计算的过程就是这种方法,所以,计算的过程和得到结果就叫算法!

如:【c = a+b;】这句语句也是算法,计算过程是a+b,计算结果是c。

如:使用for循环遍历一个列表,这也是算法,计算过程是使用for循环,计算结果就是“遍历了列表”

如:用二分搜索的方法搜索一组数据,这也是算法,计算过程是使用二分搜索,搜到的结果是所需要的某个值。

 

算法,其实任何语句都是一个算法,只是有难易的区分而已。

一般常用的算法有:用于排序的冒泡排序、插入排序、快速排序这些,用于搜索某个值的二分搜索、递归搜索、哈希搜索、二叉树等等

 

c语言标准库提供有一些算法函数,如快速排序算法qsort;

void qsort(void *base,int nelem,int width,int (*fcmp)(const void *,const void *));

base表示传入的数组,

nelem表示数组大小,

width表示数组每个数据所占的字节数

fcmp是用于比较的函数指针,用于确定排序顺序。

 

 

 

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值