链表队列二叉树.docx
《链表队列二叉树.docx》由会员分享,可在线阅读,更多相关《链表队列二叉树.docx(46页珍藏版)》请在冰豆网上搜索。
链表队列二叉树
c3链表队列二叉树
结构和其他数据形式
关键字:
struct,union,typedef
运算符:
.-
/*book.c--仅包含一本书的图书目录*/
#includestdio.h
#defineMAXTITL41
#defineMAXAUTL31structbook{//结构模板:
标记为bookchartitle[MAXTITL];
charauthor[MAXAUTL];
floatvalue;
};//结构模板结束
intmain(void)
{
structbooklibrary;//把library声明为book类型的变量
printf("Pleaseenterthebooktitle.\n");
gets(library.title);
printf("Nowentertheauthor.\n");
gets(library.author);
printf("Nowenterthevalue.\n");
scanf("%f",&library.value);
printf("%sby%s:
$%.2f\n",library.title,library.author,library.value);
printf("%s:
\"%s\"($%.2f)\n",library.author,library.title,library.value);
printf("Done.\n");
return0;
}
--
结构声明(structuredeclaration)
structbook{
chartitle[MAXTITL];
charauthor[MAXAUTL];
floatvalue;
};
structbookdickens;
structbooklibrary;
--
struct{/*无标记*/
chartitle[MAXTITL];
charauthor[MAXTITL];
floatvalue;
}library;
gets(library.title);
scanf("%f",&library.value);
structbookgift={.value=25.00,
.author="JamesBroadfool",
.title="RuefortheToad"};
---
声明结构数组
structbooklibrary[MAXBKS];
--
while(countMAXBKS&&gets(library[count].title)!
=NULL
&&library[count].title[0]!
='[message]')
--
structnames{//第一个结构
charfirst[LEN];
charlast[LEN];
};
structguy{//第二个结构
structnameshandle;//嵌套结构
charfavfood[LEN];
charjob[LEN];
floatincome;
};
printf("Hello,%s!
\n",fellow.handle.first);
---
声明和初始化结构指针
structguy*him;
him=&barney;
him=&fellow[0];
him-incomeisfellow[0].incomeifhim==&fellow[0]
fellow[0].income==(*him).incomebarney.income==(*him).income==him-income//him==&barney
---
/*names.c--使用指向结构的指针*/
#includestdio.h
#includestring.hstructnamect{
charfname[20];
charlname[20];
intletters;
};
voidgetinfo(structnamect*);
voidmakeinfo(structnamect*);
voidshowinfo(conststructnamect*);
intmain(void)
{
structnamectperson;
getinfo(&person);
makeinfo(&person);
showinfo(&person);
return0;
}
voidgetinfo(structnamect*pst)
{
printf("Pleaseenteryourfirstname.\n");
gets(pst-fname);
printf("Pleaseenteryoulastname.\n");
gets(pst-lname);
}
voidmakeinfo(structnamect*pst)
{
pst-letters=strlen(pst-fname)+
strlen(pst-lname);
}
voidshowinfo(conststructnamect*pst)
{
printf("%s%s,yournamecontains%dletters.\n",pst-fname,pst-lname,pst-letters);
}
--
#defineMAXTITL40structbook{
chartitle[MAXTITL];
charauthor[MAXTITL];
floatvalue;
}
--
C四种处理数据的特性:
结构、联合、枚举和typedef
联合(union)是一个能在同一个存储空间里(但不同时)存储不同类型数据的数据类型。
unionhold{
intdigit;
doublebigfl;
charletter;
};
unionholdfit;//hold类型的联合变量
unionholdsave[10];//10个联合变量的数组
unionhold*pu;//指向hold类型变量的指针
--
struct{
intcode;
floatcost;
}item;
item.code=1234;
问接成员运算符:
-
--
struct{
intcode;
floatcost;
}item,*ptrst;
ptrst=&item;
ptrst-code=3451;
最后一条语句将一个int值赋给item的成员code。
以下的三个表达式是等价的:
ptrst-codeitem.code(*ptrst).code
---
枚举类型(enumeratedtype)声明代表整数常量的符号名称。
enumspectrum{red,orange,yellow,green,blue,violet};
enumspectrumcolor;
typedefstruct{doublex;doubley;}rect;
--
voidshow(void(*fp)(char*),char*str)
{
(*fp)(str);//把所选函数作用于strputs(str);
}
---
枚举使得您可以创建一组代表整数常量的符号(枚举常量)
typedef工具可用来建立该函数的地址。
这个指向函数的地址可作为参数被传递给使用该函数的另一个函数。
--
位操作
运算符:
~&|^&=|=^===
二进制、十进制和十六进制记数法
位运算和位字段
~按位取反:
将每个1变为0,将每个0变为1
&位与(AND):
只有两个操作数都为1结果才为1
|位或(OR):
任意一个位操作数为1,或两个都为1,那么结果1
^位异或:
两个位操作数中有一个为1,但是不都为1,那么结果为1C有两个主要的访问位的工具,一个工具是位运算符,另一个是在结构中创建位字段的能力。
--
C预处理和C库
预处理器指令:
#define#include#ifdef#else#endif#ifndef#if#elif#line#error#pragma
函数:
sqrt(),atan(),aran2(),exit(),atexit(),assert(),memcpy(),memmove(),va_start(),va_arg(),va_copy(),va_end()
类函数宏和条件编译,内联函数
---
//names_st.h--names_st结构的头文件
//常量
#defineSLEN32
//结构声明
structnames_st
{
charfirst[SLEN];
charlast[SLEN];
}
//类型定义
typedefstructnames_stnames;
//函数原型
voidget_names(names*);
voidshow_names(constname*);
这处文件中含有头文件中常见的许多内容:
#define指令、结构声明、typedef语句和函数原型。
--
#include和#define指令是最常用的C预处理器的两个功能。
#undef指令取消定义一个给定的#define。
#defineLIMIT400
#undefLIMIT
--
//names_st.h--带有多次包含保护的修订版本
#ifndefNAMES_H_
#defineNAMES_H_
//常量
#defineSLEN32
//结构声明
structnames_st
{
charfirst[SLEN];
charlast[SLEN];
};
//类型定义
typedefstructnames_stnames;
//函数原型
voidget_names(names*);
voidshow_names(constnames*);
#endif
--
使用头文件
头文件的内容的最常见的形式包括:
明显常量--例如典型的stdio.h文件定义EOF、NULL和BUFSIZE(标准I/O缓冲区的大小)。
宏函数--例如getchar()通常被定义为getc(stdin),getc()通常被定义为较复杂的宏,而头文件ctype.h通常包含ctype函数的宏定义。
函数声明--例如头文件string.h包含字符串函数系列的函数声明。
在ANSIC中,声明采用函数原型形式。
结构模板定义--标准I/O函数使用FILE结构,该结构包含文件及文件相关缓冲区的信息。
头文件stdio.h中存放FILE结构的声明。
类型定义--可以使用指向FILE的指针作为参数调用标准I/O函数。
通常,stdio.h用#define或typedef使得FILE代表指向FILE结构的指针。
与之类似,size_t和time_t类型也在头文件中定义。
可以使用头文件来声明多个文件共享的外部变量。
使用具有文件作用域、内部链接和const限定词的变量或数组。
使用具有文件作用域、内部链接和const限定词的变量或数组。
使用const可以避免值被意外地改变。
使用static后,每个包含该头文件的文件都获得一份该变量的副本。
--
其他指令:
#undef
条件编译:
#ifdef#else#endif#ifndef#if#elif#line#error#pragma
---
预定义宏
__DATE__进行预处理的日期("Mmmddyyyy"形式的字符串文字
__FILE__代表当前源代码文件名的字符串文字
__LINE__代表当前源代码文件中的行号的整数常量
__STDC__设置为1时,表示该实现遵循C标准
__STDC_HOSTED__为本机环境设置为1,否则设为0__STDC_VERSION__为C99时设置为199901L
__TIME__源文件编译时间,格式为"hh:
mm:
ss"
__func__当前函数名
--
内联函数(inlinefunction)
把函数变为内联函数将建议编译器尽可能快速地调用该函数。
创建内联函数的方法是在函数声明中使用函数说明符inline。
---
C库:
数学库、通用工具库(包含随机数产生函数、搜索和排序函数、转换函数、内存管理函数)、诊断库
atexit()函数使用函数指针作为参数
ANSIC中,在非递归的main()函数中使用exit()函数等价于使用关键字return。
qsort()
C99标准ANSIC库:
诊断assert.h复数complex.h字符处理ctype.h错误报告errno.h浮点数环境fenv.h整数类型的格式转换inttypes.h本地化locale.h数学库math.h非本地跳转setjmp.h信号处理signal.h可变参数stdarg.h布尔支持stdbool.h通用定义stddef.h整数类型stdint.h标准I/O库stdio.h通用工具stdlib.h字符处理string.h通用类型数学tgmath.h日期和时间time.h扩展的多字节字符和宽字符工具wchar.h宽字符分类和映射工具wctype.h可选的拼写iso646.h
---
高级数据表示
用C表示多种数据类型
新的算法,以及增强您从概念上开发程序的能力
抽象数据类型(Abstractdatatype,ADT)
结构本身不能含有同类型的结构,但是它可以含有指向同类型结构的指针。
这样的定义是定义一个链表(linkedlist)的基础。
链表是一个列表,其中的每一项都包含描述何处能找到下一项的信息。
//filmlist.c--使用结构链表
#includestdio.h
#includestdlib.h//提供malloc()原型
#includestring.h//提供strcpy()原型
#defineTSIZE45//存放片名的数组大小
structfilm{
chartitle[TSIZE];
intrating;
structfilm*next;//指向链表的下一个结构
};
intmain(void)
{
structfilm*head=NULL;
structfilm*prev,*current;
charinput[TSIZE];
//收集并存储信息
puts("Enterfirstmovietitle:
");
while(gets(input)!
=NULL&&input[0]!
='[message]')
{
current=(structfilm*malloc(sizeof(structfilm));
if(head==NULL)//第一个结构
head=current;
else//后续结构
prev-next=current;
current-next=NULL;
strcpy(current-title,input);
puts("Enteryourrating1-10:
");
scanf("%d",¤t-rating);
while(getchar()!
='\n')
continue;
puts("Enternextmovietitle(emptylinetostop):
");
prev=current;
}
//给出电影列表
if(head==NULL)
printf("Nodataentered.");
elseprintf("Hereisthemovielist:
\n");
current=head;
while(current!
=NULL)
{
printf("Movie:
%sRating:
%d\n",current-title,current-rating);
current=current-next;
}
//任务已完成,因此释放所分配的内存
current=head;
while(current!
=NULL)
{
free(current);
current=current-next;
}
printf("Bye!
\n");
return0;
}
--
用抽象数据类型方法进行C语言编程包含下面三个步骤:
1.以抽象、通用的方式描述一个类型,包括其操作。
2.设计一个函数接口来表示这种新类型。
3.编写具体代码以实现这个接口。
--
队列(queue)是具有两个特殊属性的列表:
第一、新的项目只能被添加到列表结尾处
第二、项目只能从列表开始处被移除
//queue.h--队列接口头文件
#pragmac9xon
#ifndef_QUEUE_H_
#define_QUEUE_H_
#includetsdbool.h
//Item定义类型
typedefintItem;
#defineMAXQUEUE10typedefstructnode
{
Itemitem;
structnode*next;
}Node;
typedefstructqueue
{
Node*front;
Node*rear;
intitems;
}Queue;
voidInitializeQueue(Queue*pq);
boolQueueIsFull(constQueue*pg);
boolQueueIsEmpty(constQueue*pg);
intQueueItemCount(constQueue*pg);
boolEnQueue(Itemitem,Queue*pg);
boolDeQueue(Item*pitem,Queue*pg);
voidEmptyTheQueue(Queue*pg);
#endif
---
//实现接口函数
voidInitializeQueue(Queue*pg)
{
pg-front=pq-rear=NULL;
pg-items=0;
}
boolQueueIsFull(constQueue*pq)
{
returnpq-items==MAXQUEUE;
}
boolQueueIsEmpty(constQueue*pg)
{
returnpq-items==0;
}
intQueueItemCount(constQueue*pq)
{
returnpq-items;
}
boolEnQueue(Itemitem,Queue*pq)
{
Node*pnew;
if(QueueIsFull(pq))
returnfalse;
pnew=(Node*)malloc(sizeof(Node));
if(pnew==NULL)
{
fprintf(stderr,"Unabletoalloctememory!
\n");
exit
(1);
}
CopyToNode(item,pnew);
pnew-next=NULL;
if(QueueIsEmpty(pq))
pq-front=pnew;//项目位于队列首端
elsepq-rear-next=pnew;//链接到队列尾端
pq-rear=pnew;//记录队列尾端的位置
pq-items++;//队列项目个数增1returntrue;
}
staticvoidCopyToNode(Itemitem,Node*pn)
{
pn-item=item;
}
boolDeQueue(Item*pitem,Queue*pq)
{
Node*pt;
if(QueueIsEmpty(pq))
returnfalse;
CopyToItem(pq-front,pitem);
pt=pq-front;
pq-front=pq-front-next;
free(pt);
pq-item--;
if(pq-items==0)
pq-rear=NULL;
returntrue;
}
voidEmptyTheQueue(Queue*pq)
{
Itemdummy;
while(!
QueueIsEmpty(pq))
DeQueue(&dummy,pq);
}
---
//queue.c--队列类型的实现文件
#includestdio.h
#includestdlib.h
#include"queue.h"
//局部函数
staticvoidCopyToNode(Itemitem,Node*pn);
staticvoidCopyToItem(Node*pn,Item*pi);
voidInitializeQueue(Queue*pq)
{
pq-front=pq-rear=NULL;
pq-items=0;
}
boolQueueIsFull(constQueue*pq)
{
returnpq-items==MAXQUEUE;
}
boolQueueIsEmpty(constQueue*pq)
{
returnpq-items==0;
}
intQueueItemCount(constQueue*pq)
{
returnpq-items;
}
boolEnQueue(Itemitem,Queue*pq)
{
Node*pnew;
if(QueueIsFull(pq))
returnfalse;
pnew=(Node*)malloc(sizeof(Node));
if(pnew==NULL)
{
fprintf(stderr,"Unabletoallocatememory!
\n");
exit
(1);
}
CopyToNode(item,pnew);
pnew-next=NULL;
if(QueueIsEmpty(pq))
pq-front=pnew;
elsepq-rear-next=pnewpq-rear=pnew;
pq-items++;
returntrue;
}
boolDeQueue(Item*pitem,Queue*pq)
{
Node*pt;
if(QueueIsEmpty(pq))
returnfalse;
CopyToItem(pq-front,pitem);
pt=pq-front;
pq=front=pq-front-next;
free(pt);
pq-items--;
if(pq-items==0)
pq-rear==NULL;
returntrue;
}
voidEmptyTheQueue(Queue*pq)
{
Itemdummy;
while(!
QueueIsEmpty(pq))
DeQueue(&dummy,pq);
}
//局部函数
staticvoidCopyToNode(Itemitem,Node*pn)
{
pn-item=item;
}
staticvoidCopyToItem(Node*pn,Item*pi)
{
*pi=pn-item;
}
--
//use_q.c--测试Queue接口的驱动程序
//