C语言范例学习03-中
栈和队列
这两者都是重要的数据结构,都是线性结构。它们在日后的软件开发中有着重大作用。后面会有实例讲解。
两者区别和联系,其实总结起来就一句。栈,后进先出;队列,先进先出。
可以将栈与队列的存储空间比作一个只够一个身位的水管。
栈的水管,有一头被堵住了。所以当人们进去后,想出来就只能让最靠近出口的那位先出去,依次推出。(后进先出)。
队列的水管,类似单向车道。所以当人们进去后,想出来就只能一直向前,走出来,不可以从入口出来。(先进先出)。
所以,道理还是很简单的。接下来就是学习一些专属函数就ok了。
实例090 应用栈实现进制转换
问题:应用栈实现进制转换,可以将十进制数转换为其他进制数。
逻辑:首先我们来想一下进制转换的算法,就如之前提到的,不断地取余,求商。依次循环进行,再按顺序输出,获取最终结果。
代码:
#include<stdio.h>
typedef struct
{
DataType *base;
//有人问DataType是什么东东。
//DataType是一种数据类型,是数据结构专属。采取的是类C的语言。所以需要将其映射为C数据类型。
DataType *top;
int stacksize;
//提醒一句,stack是栈的英文。
}SeqStack; //************接下来就是重点
void Initial(SeqStack *s)
//栈的初始化函数,构造一个空栈S。
{
s->base=(DataType *)malloc(STACK_SIZE *sizeof(DataType));
//类似于链表的获取存储空间,连使用的函数都一样。
//注意,我这里使用的是base。所以,这个栈是“向上生长”的栈。
if(!s->base)
exit(-);
//exit()是一个退出函数,其参数是退出状态代码。(0是正常退出状态码)
s->top=s->base;
//初始化时,栈内为空。从而可以这样初始化其中的top变量。
s->stacksize=STACK_SIZE;
//获取存储空间大小。
}
int IsEmpty(SeqStack *S)
//判断栈是否为空的函数
{
return S->top==S->base;
//返回值为判断结果。
}
int IsFull(SeqStack *S)
//判断栈是否满了。
{
return S->top-S->base==STACK_SIZE-;
//注意看,中间那个是减号。
}
void Push(SeqStack *S,DataType x)
//栈的入栈函数
{
if(IsFull(S))
{
printf("栈上溢出");
exit();
}
*S->top++=x;
//入栈时,切记 栈指针top,“先压后加”。
}
DataType Pop(SeqStack *S)
//栈的出栈函数
{
if(IsEmpty(S))
{
printf("栈为空");
exit();
}
return *--S->top;
//注意上面是*(--s),别问我*--是什么。出栈时,切记 栈指针to[,“先减后弹”。
}
DataType Top(SeqStack *S)
//栈顶变化函数。
//因为这个栈是从栈底构建的,所以栈底不变。变化的是栈顶。
{
if(IsEmpty(S))
{
printf("栈为空");
exit();
}
return *(S->top-);
//改变栈顶地址。
}
//************以上是重点 void conversion(int N,int B)
//解决问题的进制转换函数
{
int i;
SeqStack *S;
Initial(S);
//初始化栈S
while(N)
{
Push(S,N%B);
N=N/B;
}
//这个循环不用我讲了吧。就知平时进制转化的循环。
while(!IsEmpty(S))
{
i=Pop(S);
printf("%d",i);
//依次输出栈中元素,其实就是我们的结果了。
}
}
void main()
//主函数不用细讲。就是完成输入,输出,调用变换函数。
{
int n,d;
printf("Input the integer you want to transform:");
scanf("%d",&n);
printf("Input the integer of the system:");
scanf("%d",&d);
printf("result:");
conversion(n,d);
getch();
}
反思:栈的应用主要就是初始化、判断空、判断满、入栈、出栈、栈顶六个函数。懂了这六个函数,应用就没什么了。
其中的技巧,代码备注也提到了,比如:“先压后加”等。不过这是针对这个栈的,一个“向上生长”的栈。
ps:其实还有用栈设置密码、实现编辑程序等。但其中关于栈的部分基本大同小异,所以不再赘述。
如果,还有不懂,可以看看视屏。比如,张洪瑞与严蔚敏老师的视屏讲解。(我不会告诉你,计算机考研的专业课可是要求严蔚敏老师的书。不过建议张洪瑞老师的视屏。主要严蔚敏老师讲的。总感觉和我不是一个时代,事实上,也确实不是一个时代的。)
实例095 链队列
问题:采取链式存储法编程实现元素入队、出队以及将队列中的元素显示出来,要求整个过程以菜单选择的形式实现。
逻辑:逻辑与栈没有太多区别。将队列的主要操作:创建、入队、出队、展示等功能分为多个函数进行。最后主函数实现题目要求的界面功能,及输入,调用等功能。
代码:
#include<stdio.h>
#include<stdlib.h>
typedef int ElemType;
//怕你们不懂之前说的DataType到底怎么弄。这个就是一个例子。如果没有这句话,你们会发现在VC里,这个程序报错报炸了。
typedef struct node
//这个结构体是用来存储节点的。
{
ElemType data;
//节点数据
struct node *next;
//节点指向下一个节点地址
}quenode;
//这个节点结构体名称。
struct quefr
//这个结构体用来存放队列的队首、队尾地址指针。
{
quenode *front,*rear;
//quenode是什么?额,就是我们之前定义的节点结构体。
};
void creat(struct quefr *q)
//定义函数creat,用来创建、初始化队列。
{
quenode *h;
h=(quenode*)malloc(sizeof(quenode));
//获取存储空间,空间大小与quenode同步。
h->next=NULL;
//初始化h->next,为空。
q->front=h;
q->rear=h;
//初始化相关的quefr中数据,均为h。(队列刚刚建立,那么队首,队尾当然是同一个元素(结构体quenode的h))。
}
void enqueue(struct quefr *q,int x)
//定义入队函数enqueue,用来实现元素x进入队列q。
{
quenode *s;
//建立一个新的节点s,用来存储新的入队元素x。
s=(quenode*)malloc(sizeof(quenode));
//依旧是获取存储空间
s->data=x;
//向quenode结构体s导入新的入队元素x。
s->next=NULL;
//s的指针域设置为空,作为初始化。
//也许,有人就问了。这里设置为空,那么队列还怎么连接起来啊。
//嗯。其实,有关连接方面的数据处理统一交给了quefr处理了。看下面就知道了。
q->rear->next=s;
//这里实现了队列元素的连接。切记,其中rear指针的数据类型可是quenode,所以可以实现调用next,可以实现连接。
q->rear=s;
//这时队尾指针地址改变,因为增加了新的元素了。(这个程序设定是队首地址不变的,向队尾添加元素。)
//我这个程序设定的是队尾入队,队首出队。
}
ElemType dequeue(struct quefr *q)
//定义出队函数dequeue,用来实现元素离开队列q。(由于,之前提到的队列性质,所以离开队列的函数必然是队首元素。)
{
quenode *p;
ElemType x;
//初始化,详细参考上面的。
p=(quenode*)malloc(sizeof(quenode));
//有人说,初始化,入队要获取存储空间就算了。为什么出队还要获取存储空间呢?
//其实,不是没有道理。但是,1,我们对数据处理部分采用的一直都是结构体quenode,出队是便于数据处理,当然还是得建立结构体,自然就要获取存储空间;2.很简单一句,便于模块化操作。
if(q->front==q->rear)
//判断原队列是否为空
{
printf("queue is NULL\n");
x=;
}
else
{
p=q->front->next;
//赋值指针p,为q指针的下一个地址。
q->front->next=p->next;
//重新定位q->front->next,从而重新定位了q。
//这两句也许有些人会看得有点晕,可以自己画画图,或者参考一些之前的链表。主要就是把原来q的地址遗失了。重新定位q。
if(p->next==NULL)
//判断原队列是否就一个元素
q->rear=q->front;
//重新定位。很好奇这步有没有必要。
x=p->data;
//获取出队列元素
free(p);
//释放空白空间。
}
return(x);
//返回出队元素
}
void display(struct quefr dq)
//定义函数display,用于展示队列内的所有元素
{
quenode *p;
p=(quenode*)malloc(sizeof(quenode));
//为p分配存储空间
p=dq.front->next;
//赋值p
while(p!=NULL)
//等同于判断dq.front->next是否不为空
{
printf("data=%d\n",p->data);
//展示元素
p=p->next;
//将计数器指向下一个元素地址。
}
printf("end\n");
//最终输出end,表示元素展示完毕。
}
main()
//建立主函数作为程序入口,实现题目要求的界面,以及输入,调用,输出。
{
struct quefr *que;
//定义*que的数据类型为struct quefr。
int n,i,x,sel;
void display();
void creat();
void enqueue();
ElemType dequeue();
do
{
printf("\n");
printf(" 1 creat queue \n");
printf(" 2 into the queue \n");
printf(" 3 delete from queue \n");
printf(" 4 display \n");
printf(" 5 exit \n");
printf("--------------------------------------------\n");
printf("please choose(1,2,3,4,5)\n");
scanf("%d",&sel);
switch(sel)
//采用switch判断语句。
{
case :
que=(struct quefr*)malloc(sizeof(struct quefr));
creat(que);
printf(
"please input the number of element which do you want to creat:");
scanf("%d",&n);
for(i=;i<=n;i++)
{
scanf("%d",&x);
enqueue(que,x);
}
break;
case :
printf("please input the element:");
scanf("%d",&x);
enqueue(que,x);
break;
case :
printf("x=%d\n",dequeue(que));
break;
case :
display(*que);
break;
case :
exit();
}
}
while(sel<=);
//使用了do while循环。当sel为5时,sel>4,跳出循环。
}
反思:之所以将队列的问题分为多个函数分别解决,是为了更好地模块化操作。越发地感受到编程中模块化操作的重要性,及好处。
实例096 循环缓冲区问题
ps:这个问题原本想将代码打出来的,但我觉得之前队列程序已经将主要架构显现出来了。所以这个问题只会简单一提,如果有人有需要,可以找我要。
逻辑:队列的这个实例主要采用了循环队列。可以很好地解决顺序队列“假溢出“的现象。这里的循环队列和之前循环链表一样,就是将顺序队列构建成一个首尾相连的循环表。这样可以更好地解决我之前在循环链表提到的循环存储问题。
总结:到此为止,栈与队列队列的问题就差不多了。你会发现,这两个就是差不多的东西。事实上,也就两种特殊的顺序表。操作思想是一致的。更重要的是体会到其中越发明显的模块化操作的思想。
串与广义表
编程中的数据处理,无非数值处理与非数值处理,而非数值处理基本上是字符串数据。而现在计算机的硬件及其架构更多地是为了数值计算,所以相对而言,处理字符串数据就更为复杂了。其中广义表是线性表的推广,目前多用于人工智能等领域的表处理语言中。所以,有这方面兴趣的可以多多关注。
实例098 简单的文本编辑器
问题:要求实现三个功能:第一,要求对指定行输入字符串;第二,删除指定行的字符串;第三,显示输入的字符串的内容。
逻辑: 串其实就是由零个,或多个字符串组成的有限序列。
串的存储方式由两种:静态存储与动态存储。 其中动态存储结构又有两种:链式存储结构与堆结构存储。这个问题的解决采用了链式存储结构。
串的链式存储结构是包含数据域和指针域的节点结构(是不是感觉很眼熟,和链表好像啊)。
由于每个节点只存放一个字符,太过浪费空间,为节省空间,故令每个节点存放若干个字符(题目中采用了50个字符为一块),这种结构叫块链结构。(题目中采用了这种结构)。
代码:
#include<stdio.h>
#include<stdlib.h>
#define MAX 100
void Init();
void input();
void Delline();
void List();
int Menu();
//仅仅是函数声明,由于主函数位于最后面,所以这五个语句去掉也可以。 typedef struct node
//定义存放字符串的节点。
{
char data[];
struct node *next;
}strnode; typedef struct head
//定义每行的头结点。
{
int number;
int length;
strnode *next;
}headnode;
//如之前的一样,两个结构体,前者作为数据节点,存储数据,后者则负责存储的位置等数据以外的事情。 headnode Head[MAX];
//定义有100行。 void Init()
//定义函数Init,用来初始化串。
{
int i;
for(i=;i<MAX;i++)
{
Head[i].length=;
//设定长度均为0
}
} int Menu()
//定义函数Menu,用来控制函数的人机交互界面。
{
int i;
i=;
printf("1.Input\n");
printf("2.Delete\n");
printf("3.List\n");
printf("4.Exit\n");
while(i<=||i>)
{
printf("please choose\n");
scanf("%d",&i);
}
return i;
//返还用户的输入函数
} void input()
//定义函数input,作为串的输入函数。
{
strnode *p,*find();
int i,j,LineNum;
char ch;
while()
{
j=-;
//这里j=-1,其实,由于采用的是while(1)循环。计数器的增加在开头 j++。所以,其实还是从j=0开始的。
printf("input the number of line(0-100),101-exit:\n");
scanf("%d",&LineNum);
//输入要输入字符串的所在行数。
if(LineNum<||LineNum>=MAX)
return;
//超出可能的行数,即直接返回。
printf("please input,#-end\n");
i=LineNum;
Head[i].number=LineNum;
Head[i].next=(strnode*)malloc(sizeof(strnode));
//申请存储空间。
p=Head[i].next;
//p就是我们将要存储字符串的头结点(字符串的第一个字符的地址)
ch=getchar();
while(ch!='#')
{
j++;
//验证前面所说的j问题
if(j>=)
//这里采用了50为一行字符串的上限。
{
p->next=(strnode*)malloc(sizeof(strnode));
p=p->next;
//大于50了,就会重新申请存储空间,继续存储字符串。所以一个head节点只存储50字符串长度的数据。
//但是,由于我们并没有修改number,所以在其表现来看,我们输入的超过50字符的字符串还是同一个字符串。
//这里可以将这个方法,应用到更多的地方。
}
p->data[j%]=ch;
//理解j%50即可。
ch=getchar();
}
Head[i].length=j+;
//因为我们j是从0开始的。
}
} void Delline()
//定义函数Delline(),用来删除确定的字符串。
{
strnode *p,*q;
int i,LineNum;
while()
{
printf("input the number of line which do you want to delete(0-100),101-exit:\n");
scanf("%d",&LineNum);
//输入具体要删除的字符串所在的行数。
if(LineNum<||LineNum>=MAX)
return;
i=LineNum;
p=Head[i].next;
//中间这四行代码同input函数一样
if(Head[i].length>)
//判断所要删除的函数并非空
while(p!=NULL)
//判断所要删除字符串的下一个字符串非空时,采取的处理。
{
q=p->next;
free(p);
p=q;
//和之前链表,栈等的删除相同。
}
Head[i].length=;
Head[i].number=;
//确定该字符串的头文件中length、number均为0,等同于消除存在。
//正如之前Head[i].length>0这句代码,有时可通过对length、number的判断来显示,该Head是否为空。
}
} void List()
//自定义函数List(),用来展示所有的字符串。
{
strnode *p;
int i,j,m,n;
for(i=;i<MAX;i++)
//老样子,这个串,说白了数据深度就两层。所以两个循环就OK了。第二个循环在后面。要看成整体,中间只是多个判断和顺序。
//其中我是用printf一个字符一个字符地输出的。所以一个字符串就是一层循环。
//但是,如果你要换成一个字符串一个字符串的输出,类似putstr。自己改啊。
{
if(Head[i].length>)
//这里就验证了之前提到的用length判断是否为空。空时就不会输出该字符串了。
{
printf("line%d: ",Head[i].number);
//输出所要输出字符串所在的行数。
n=Head[i].length;
m=;
p=Head[i].next;
for(j=;j<n;j++)
//第二个循环。用来将字符串中字符一个一个输出。
if(j>=*m)
//还记得我之前在输入函数中提到的50长度的问题吗?这里就有了解决之道。
{
p=p->next;
m++;
}
else
printf("%c",p->data[j%]);
//输出一个个字符。
printf("\n");
}
}
printf("\n");
} main()
//创建主函数mian(),作为程序的入口。控制程序的选择界面、函数调用等。
{
int sel;
Init();
while()
{
sel=Menu();
switch(sel)
{
case :
input();
break;
case :
Delline();
break;
case :
List();
break;
case :
exit();
}
}
//主函数不做解释了。这和之前的一模一样啊。
}
反思:其中关于块链结构的应用那两段代码,应当好好理解。是个很好用的思路。
实例099 广义表的存储 实例100 广义表的存储
ps:广义表是一种非线性的列表。是线性表和树的推广。广泛应用与人工智能领域。有兴趣的小伙伴要多多注意了。
问题:我将两个问题和在了一起。编程实现用动态链接结构存储广义表与广义表的复制,要求输出该广义表的长度和深度,以及表头和表尾。
逻辑: 在一个广义表中,数据元素可以是一个单一元素,也可以是子表,相应地在对应的存储结构中,存储结构节点也有单元素节点和子表节点之分。单元素节点包含值域和指向其后继结点的指针域。对于子表节点,应包含指向子表中第一个节点的表头指针和指向其后继结点的指针域。为了区分广义表中单元素节点和子表元素,我们设置tag作为标志,当tag=0时表示本节点为单元素,当tag=1时表示本节点为子表。
当tag=1时,说明其为子表节点,则第二域是sublist域,存放的是指向其子表的指针,next域存放指向与该节点同层的直接后继结点的指针,当该节点是所在层的最后一个节点时,此时next为空(和之前链表等,一样)。
广义表的复制可以采用递归实现。
其实,广义表这个东西如果有图,看一下图,就立马懂了。我过会儿找找,有的话,就贴上。(我才不会说,我还不知道怎么添加图片呢。)
代码:
#include<stdio.h>
#include<stdlib.h>
typedef char ElemType;
//替换的实现
typedef struct lnode
//
{
int tag;
union
//由于,节点元素要么是单一元素,要么是子表元素。所以采用了union来统一管理,同时实现存储空间的节约。
{
ElemType data;
//用来存放单一元素。
struct lnode *sublist;
//用来存放子表元素--子表头结点指针地址。
}val;
//值域
struct lnode *next;
//指向后继节点的指针域。
}GLNode;
//广义表结构体名。 void creatGList(struct lnode **gl)
//创建函数creatGList(),用来实现广义表的创建。
{
char ch;
ch=getchar();
if(ch=='#')
{
*gl=NULL;
}
else if(ch=='(')
//输入的字符若是左括号,则建立子表。
{
*gl=malloc(sizeof(struct lnode));
//创建存储空间。
(*gl)->tag=;
//表明是子表
creatGList(&((*gl)->val.sublist));
//调用函数creatGList(),创建子表。
}
else
{
*gl=malloc(sizeof(struct lnode));
//创建存储空间
(*gl)->tag=;
//表明是字符。
(*gl)->val.data=ch;
//存储输入的字符。
}
ch=getchar();
if(*gl==NULL)
{
;
}
else if(ch==',')
//输入的是",",表示递归构造后继表。
{
creatGList(&((*gl)->next));
}
else
(*gl)->next=NULL;
return;
} void printGList(struct lnode *gl)
//创建函数printGList(),用于输出广义表。
{
if(gl->tag==)
//如果类型是子表,则输出括号
{
printf("(");
//先输出左括号
if(gl->val.sublist==NULL)
{
printf("#");
}
else
{
printGList(gl->val.sublist);
//递归输出子表
}
printf(")");
//输出右括号
}
else
//否则,即输出的是字符。
printf("%c",gl->val.data);
//直接输出字符。
if(gl->next!=NULL)
{
printf(",");
printGList(gl->next);
//递归输出后继表。
}
return;
} int GLLength(GLNode *gl)
//创建函数GLLength(),用来计算广义表的长度。
{
int n=;
gl=gl->val.sublist;
while(gl!=NULL)
{
n++;
//长度计数。
gl=gl->next;
//指向下一个节点。
}
return n;
} int GLDepth(GLNode *gl)
//创建函数GLDepth(),用来计算广义表的深度。
{
int max=,dep;
if(gl->tag==)
return ;
gl=gl->val.sublist;
if(gl=NULL)
return ;
while(gl!=NULL)
{
if(gl->tag==)
//类型为子表
{
dep=GLDepth(gl);
//递归计算广义表的深度。
if(dep>max)
max=dep;
//记录下最大深度。
}
gl=gl->next;
//指向下一个节点。
}
return(max+);
} GLNode *GLCopy(GLNode *gl)
//创建函数GLCopy(),用来实现广义表的复制。
{
GLNode *q;
if(gl==NULL)
return NULL;
q=(GLNode*)malloc(sizeof(GLNode));
//申请存储空间
q->tag=gl->tag;
//复制元素类型。
if(gl->tag==)
q->val.sublist=GLCopy(gl->val.sublist);
//递归复制子表
else
q->val.data=gl->val.sublist;
//递归复制数据元素
q->next=GLCopy(gl->next);
//复制next信息,指向下一个节点,递归复制。
return q;
}
GLNode *head(GLNode *gl)
//创建函数head(),用来实现计算广义表的表头。
{
GLNode *p=gl->val.sublist;
//初始化,赋值p.
GLNode *q,*t;
//初始化q,t。
if(gl==NULL)
{
printf("NULL\n");
return NULL;
}
if(gl->tag==)
//如果广义表为空。
{
printf("atom is not head! \n");
//输出广义表没有表头。
return NULL;
}
if(p->tag==)
//如果元素的类型为字符
{
q=(GLNode*)malloc(sizeof(GLNode));
//为q申请存储空间。
q->tag=;
//记录数据类型
q->val.data=p->val.data;
//复制数据。
q->next=NULL;
//单个元素的下一个节点为空。
}
else
{
t=(GLNode*)malloc(sizeof(GLNode));
//申请存储空间。
t->tag=;
//记录元素的类型为子表
t->val.sublist=p->val.sublist;
//赋值子表
t->next=NULL;
//单个元素的下一个节点为空。
q=GLCopy(t);
//复制子表。
free(t);
//释放t的存储空间。
}
return q;
//返回q。
} GLNode *tail(GLNode *gl)
//创建函数tail(),用来计算广义表的表尾。
//概念同上,故不做注释。参考上一个函数。
{
GLNode *p=gl->val.sublist;
GLNode *q,*t;
if(gl==NULL)
{
printf("NULL\n");
return NULL;
}
if(gl->tag==)
{
printf("atom is not tail!\n");
return NULL;
}
p=p->next;
t=(GLNode*)malloc(sizeof(GLNode));
t->tag=;
t->val.sublist=p;
t->next=NULL;
q=GLCopy(t);
free(t);
return q;
} main()
//创建主函数main(),作为程序入口。用来执行输入、调用函数等功能。
{
int len=;
int dep=;
struct lnode *g,*v;
struct lnode *h;
printf("Input Example: (a,b,(c,d,(e,f,g),h,i),j)");
printf("\n");
printf("PS:输入的‘()’是圆括号,并不是尖括号。");
//添加备注。
printf("\n");
creatGList(&h);
//创建广义表。切记这里是&h。
len=GLLength(h);
//计算广义表长度。
dep=GLDepth(h);
//计算广义表深度。
printf("\n");
printf("The length is:");
printf("%d",len);
printf("\n");
printf("The depth is:");
printf("%d",dep);
printf("\n");
v=head(h);
g=tail(h);
//赋值。
if(v!=NULL)
//计算,并输出广义表的表头。
{
printf("The Head is:");
printGList(v);
printf("\n");
}
if(g!=NULL)
//计算,并输出广义表的表尾。
{
printf("The Tail is:");
printGList(g);
printf("\n");
}
if(h!=NULL)
//展示整个广义表。
{
printf("Glist is:");
printGList(h);
printf("\n");
}
else
printf("Glist is NULL");
}
反思:其中有着不少的小点,需要记忆、理解。值得好好看看。
PS:1.关键字union:union 关键字的用法与struct 的用法非常类似。
union 维护足够的空间来置放多个数据成员中的“一种”,而不是为每一个数据成员配置空间,在union 中所有的数据成员共用一个空间,同一时间只能储存其中一个数据成员,所有的数据成员具有相同的起始地址。例子如下:
union StateMachine
{
char character;
int number;
char *str;
double exp;
};
一个union 只配置一个足够大的空间以来容纳最大长度的数据成员,以上例而言,最大长度是double 型态,所以StateMachine 的空间大小就是double 数据类型的大小。
在C++里,union 的成员默认属性页为public。union 主要用来压缩空间。如果一些数据不可能在同一时间同时被用到,则可以使用union。
以上关于union的说明采摘自:http://c.biancheng.net/cpp/html/450.html, 其中还有关于大小端模式、确认系统大小端方法的具体说明,感兴趣的可以看一看。
到这里,栈与队列,串与广义表就完成了。下一次就是这章的最后知识点--树与图。
C语言范例学习03-中的更多相关文章
- C语言范例学习04
第三章 算法 前言:许多人对算法的看法是截然不同的,我之前提到过了.不过,我要说的还是那句话:算法体现编程思想,编程思想指引算法. 同时,有许多人认为简单算法都太简单了,应当去学习一些更为实用的复杂算 ...
- C语言范例学习03-上
第三章 数据结构 章首:不好意思,这两天要帮家里做一些活儿.而且内容量与操作量也确实大幅提升了.所以写得很慢. 不过,从今天开始.我写的东西,许多都是之前没怎么学的了.所以速度会慢下来,同时写得也会详 ...
- C语言范例学习01
编程语言的能力追求T型. 以前学过C语言,但是只学了理论. 从今天开始,我买了本<C语言程序开发范例宝典>.我要把它通关掉. 这应该可以极大地提升我的编程能力. 第一章 基础知识 这章没太 ...
- C语言范例学习06-上
第六章 文件操作 前言:第五章是C语言在数学上的一些应用,我觉得没有必要,便跳过了.这章正如我标题所写的,是C语言在文件上的操作.学习了这个后,你们可以自行编辑一些所需的快捷程序,来实现一些既定的目的 ...
- C语言范例学习02
第二章 指针 算是重点吧,这也是C语言的特色啊,直接访问物理存储. 重点: 指针就是一个存放它指向变量地址的变量,好绕口. 区分*在定义是与引用是的作用. 区分*.&的不同. 指针 ...
- c语言基础学习03
=============================================================================涉及到的知识点有:编码风格.c语言的数据类型. ...
- C语言范例学习03-下
树与图 3.5 二叉树及其应用 PS:二叉树是最经典的树形结构,适合计算机处理,具有存储方便和操作灵活等特点,而且任何树都可以转换成二叉树. 实例101 二叉树的递归创建 实例102 二叉树的遍历 问 ...
- Go语言学习03
Go语言-数组类型 一个数组(Array)就是一个可以容纳若干类型相同的元素的容器.这个容器的大小(即数组的长度)是固定的,且是体现在数组的类型字面量之中的.比如,我们声明了一个数组类型: type ...
- GO学习-(36) Go语言在select语句中实现优先级
Go语言在select语句中实现优先级 Go语言在select语句中实现优先级 select语句介绍 Go 语言中的 select语句用于监控并选择一组case语句执行相应的代码.它看起来类似于swi ...
随机推荐
- C primer plus 练习题 第七章
1. #include <stdio.h> #define SPACE ' ' #define NEWLINE '\n' int main() { int spaces,newlines, ...
- git 在提交之前撤销add操作
问题 在使用git时,在未添加.ignore文件前使用 git add . 将所有文件添加到库中,不小心将一些不需要加入版本库的文件加到了版本库中.由于此时还没有提交所以不存在HEAD版本,不能使用 ...
- LeetCode:4_Median of Two Sorted Arrays | 求两个排序数组的中位数 | Hard
题目: There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the ...
- 将Word转为带书签的PDF
将word文档存为PDF可以带来很多便利,在这里就不多说了.下面讨论一下转换方法. 我现在使用的是Word2010+Acrobat9,所以这里仅讨论使用这种组合的转换方法. 在Word2010中有两种 ...
- 【转载】 IE/Firefox每次刷新时自动检查网页更新,无需手动清空缓存的设置方法
[参考了别人的文章]我们做技术,经常在写页面的时候需要多次刷新测试,可是浏览器都有自己的 缓存机制,一般CSS和图片都会被缓存在本地,这样我们修改的CSS就看不到效果 了,每次都去清空缓存,再刷新看效 ...
- 如何在mac os中安装gdb及为gdb进行代码签名
1. 安装gdb GDB作为一个强大的c/c++调试工具,一直是程序猿们的良好伴侣,但转到Mac os才发现竟然没有默认安装,所幸还有强大的homebrew工具: brew install homeb ...
- C#调用Java类
C#调用Java类 (2011-01-07 14:02:05) 转载▼ 分类: Java学习 1. 在Eclipse中新建名称为hello的java project,此工程仅包含一个文件hell ...
- 整合ssh model $$_javassist_13 cannot be cast to javassist.util.proxy.Proxy
经goole stackoverflow 发现是 javassit 包冲突 项目使用的是maven 检查依赖包
- 玩转spring boot——properties配置
前言 在以往的java开发中,程序员最怕大量的配置,是因为配置一多就不好统一管理,经常出现找不到配置的情况.而项目中,从开发测试环境到生产环境,往往需要切换不同的配置,如测试数据库连接换成生产数据库连 ...
- 使用Html5+C#+微信 开发移动端游戏详细教程 :(二)准备工作&开发环境
C#开发环境:VS2013; H5开发环境:WebStorm; 数据库:mysql+navicat管理工具: 操作系统:win7: 调试:chrome浏览器 如果想在微信端上线运营游戏请做好以下准备工 ...