因最先进入队列的结点将最先出队,所以队列具有先进先出的特性。
可以用顺序存储线性表来表示队列,也可以用链表实现,用链表实现的队列称为链队列。
队列操作:
①intpush(PNODE*top,inte>是进栈函数,形参top是栈顶指针的指针,形参e是入栈元素。
②intpop(PNODE*top,intoe>是出栈函数,形参top是栈顶指针的指针,形参e作为返回出栈元素使用。
③intenQueue(PNODE*tail,inte>是入队函数,形参tail是队尾指针的指针,形参e是入队元素。
④intdeQueue(PNODE*tail,int*e>是出队函数,形参tail是队尾指针的指针,形参e作为返回出队元素使用。
定义结点的结构如下:
typedefstructnode{
intvalue。
structnode*next。
}NODE,*PNODE。
[函数①]
intpush(PNODE*top,inte>
{
PNODEp=(PNODE>malloc(sizeof(NODE>>。
if(!
p> return–1。
p->value=e。
p->next=*top。
//指向栈顶指针
*top=p。
return0。
}
[函数②]
intpop(PNODE*top,int*e>
{
PNODEp=*top。
if(p==NULL>return–1。
*e=p->value。
*top=p->next。
//栈顶指向取出的数的指针
free(p>。
return0。
}
[函数③]
intenQueue(PNODE*tail,inte>
{ PNODEp,t;
t=*tail。
p=(PNODE>malloc(sizeof(NODE>>;
if(!
p>return–l。
p—>value=e。
p—>next=t—>next。
t->next=p。
//将元素加在尾指针后
*tail=p。
return0。
}
[函数④]
intdeQueue(PNODE*tail,inte>
{
PNODEp,q;
if((*tail>->next==*tail>return–1。
//队列已经空
p=(*tail>->next。
//p获得尾指针
q=p->next。
e=q->value。
p->next=q->next。
if(*tail=q>
*tail=p。
//尾指针指向最后节点
free(q>。
return0。
>
循环队列(CircularQueue>:
存储队列的数组被当作首尾相接的表处理。
队头、队尾指针加1时从maxSize-1直接进到0,可用语言的取模(余数>运算实现。
队头指针进1:
front=(front+1>%maxSize。
队尾指针进1:
rear=(rear+1>%maxSize。
队列初始化:
front=rear=0。
队空条件:
front==rear。
队满条件:
(rear+1>%maxSize==front
循环队列的进队和出队:
优先级队列:
是不同于先进先出队列的另一种队列。
每次从队列中取出的是具有最高优先权的元素
2.4串
字符串是非数值处理应用中重要的处理对象。
字符串是由某字符集上的字符所组成的任何有限字符序列。
当一个字符串不包含任何字符时,称它为空字符串。
一个字符串所包含的有效字符个数称为这个字符串的长度。
一个字符串中任一连续的子序列称为该字符串的子串。
包含子串的字符串相应称为主串。
通常称该字符在序列中的序号为该字符在串中的位置。
字符串的串值必须用单引号括,‘c1c2c3…cn起来,但单引号本身不属于串,它的作用是为了避免于变量名和数的常量混淆。
在C语言中,字符串常量是用一对双引号括住若干字符来表示,如“Iamastudent”
字符串通常存于字符数组中,每个字符串最后一个有效字符后跟一个字符串结束符“\0”.系统提供的库函数形成的字符串会自动加结束符号,而用户的应用程序中形成的字符串必须由程序自行负责添加字符串结束符号。
两个串相等当且仅当两个串的值相等,长度相等并且各个对应位置的字符都相等。
常用的字符串的基本操作有7种。
ASSING
EQUAL
LENGTH
CONCAT
SUBSTR
INDEX
REPLACE
INSERT
DELETE
(1>求字符串长,intstrlen(chars>
<2)串复制(copy>
char*strcpy(charto,charfrom>。
该函数将串from复制到串to中,并且返回一个指向串to的开始处的指针。
(3>联接(concatenation>
char strcat(charto,charfrom>
该函数将串from复制到串to的末尾,并且返回一个指向串to的开始处的指针。
(4>串比较
intstrcmp(chars1,chars2>。
该函数比较串s1和串s2的大小,当返回值小于0,等于0或大于0时分别表示s1s2
例如:
result=strcmp(“baker”,”Baker”> result>0
result=strcmp(“12”,”12”>。
result=0
result=strcmp(“Joe”,”Joseph”>。
result<0
<5)字符定位(index>
charstrchr(chars,charc>。
该函数是找c在字符串中第一次出现的位置,若找到则返回该位置,否则返回NULL。
字符串的静态存储:
顺序存储,用一组地址连续的地址单元存储串的字符序列,特别是在PASCAL程序语言中还可以采用紧缩数组来实现。
字符串的动态存储:
采用链表的方式存储字符串,节点的大小可以不同,即每个节点可以存放的字符数是不同的。
对于节点大小大于1的链表,需要设置头指针和尾指针来定位和串连接。
存储密度:
串值所站的存储位/实际分配的存储位
实际应用的串处理系统中采用的是动态存储结构,每个串的值各自存储在一组地址连续的存储单元中,存储地址在程序执行过程中动态分配。
利用串名和串值之间的的对应关系来建立存储映象来访问串。
2.5数组
数组是最常用的数据结构之一,在程序中,数组常用来实现顺序存储的线性表。
数组由固定个数的元素组成,全部元素的类型相同,元素依次顺序存储。
每个元素对应一个下标,数组元素按数组名和元素的下标引用,引用数组元素的下标个数称为数组的维数。
在C语言中,n个元素的数组中,第一个元素的下标为0,最后一个的下标为n-1。
数组可以分为一维、二维……N维数组,取决于引用数组元素的下标的个数;
一维数组:
二维数组和三维数组:
数组可以分为静态数组和动态数组两类,所谓静态就是指数组的空间存储分配是在使用之前还是在程序运行当中分配,静态数组就是在定义时必须进行空间分配,也就是固定数组的大小,这样就不利于数组的扩展。
同样动态数组就是在程序运行过程中进行数组的赋值或者是空间的分配,动态数组一般采用链表的存储结构,而静态数组一般采用顺序存储结构。
数组元素可以是任何类型的,当元素本身又是数组时,就构成多维数组。
多维数组是一维数组的推广,多维数组中最常用的是二维数组。
多维数组的所有元素并未排在一个线性序列里,要顺序存储多维数组按需要按一定次序把所有的数组元素排在一个线性序列里,常用的排列次序有行优先顺序和列优先顺序。
对于多维数组,C语言按行优先顺序存放。
对于数组,通常只有两种操作:
给定一个下标,存取相应的数据元素
给定一组下标,修改相应数据元素的某一个或几个数据项的值。
一般用多维数组表示矩阵,具体有以下几种类型:
对称矩阵:
A[i,j]==A[j,i]
三角矩阵:
以主对角线划分,三角矩阵有上三角和下三角两种。
上三角矩阵中,它的下三角<不包括主对角线)中的元素均为常数。
下三角矩阵正好相反,它的主对角线上方均为常数,在大多数情况下,三角矩阵常数为零。
三角矩阵可压缩存储到向量sa[0..n(n+1>/2]中,sa[k]和aij的对应关系是:
k=
3、对角矩阵
对角矩阵中,所有的非零元素集中在以主对角线为了中心的带状区域中,即除了主对角线和主对角线相邻两侧的若干条对角线上的元素之外,其余元素皆为零。
当∣i-j∣>1时,元素a[i,j]=0。
LOC(i,j>=LOC(0,0>+[3*i-1+(j-i+1>]=LOC(0,0>+(2i+j>
4.稀疏矩阵
简单说,设矩阵A中有s个非零元素,若s远远小于矩阵元素的总数<即s≦m×n),并且分布没有一定规律。
用顺序存储结构的三元组对稀疏矩阵进行存储,分别记录行、列和值
十字链表:
由于非零元的位置和个数变化,所以用链表存储更恰当;在这种情况下采用十字链表来表示,每个非零元用一个节点表示,节点中有行、列还有向下的域和线右的域;
此外还需要一个指向列链表的表头节点和指向行链表的表头节点。
还可以设置一个指向整个十字链表的表头节点。
还可以把列表头和行表头节点组成数组,便于操作;
各种广义表示意图
2.6树
2.6.1概述
树型结构是一类重要的非线性数据结构。
其中以树和二叉树最为常用,直观看来,树是以分支关系定义的层次结构。
树是由一个或多个结点组成的有限集T,它满足以下两个条件:
I. 有一个特定的结点,成为根结点
II.其余的结点分成m=0)个互不相交的有限集T0,T1,…,Tm-1。
其中每个集合又都是一棵树,称T0,T1,…,Tm-1为根结点的子树。
这里可以看出树的定义是递归的,即一棵树由子树构成,子树又由更小的子树构成。
一个结点的子树数目,称为结点的度。
树中各结点的度的最大值则称为树的度。
树中结点的最大层次称为树的深度。
如果将树中结点的各子树看成从左到右是有次序的<即不能交换),则称该树为有