内容
1.BM算法
2.栈的使用
3.利用哈弗曼树实现文件压缩
4.约瑟夫问题
5.链表的相关操作
6.栈、队列的相关操作
7.树的相关操作
1.BM算法
//好后缀规则和坏字符规则
//j+max(shift(好后缀),shift(坏字符))
/*文本串和模式串进行匹配;
模式串共有m个,从0—(m-1)
设计数组bmBc[k]表示坏字符k在模式串中出现的位置距离模式串末尾的最大长度;
遇到坏字符时,模式串可以移动距离为:shift(坏字符)=bmBc[T[i]]-(m-i-1)
i表示匹配的第一个字符在模式串中的位置,0,1,2,3,****
T[i]为模式串的第一个字符对应的文本串
(m-1-i)为i到模式串最后一个字符的距离
*/
#include
#define ASIZE 256 //把ASCII表中的256个字符表示全,不会漏掉字符
void preBmBc(char *x,int m,int bmBc[])
{
int i;
for(i=0;i
//好后缀规则移动模式串 shift(好后缀)
//1.模式串中有子串匹配上好后缀,移动模式串,让子串和好后缀对其;
若超过一个子串匹配上好后缀,则选择最左边的子串对齐
2.模式串中没有子串匹配上好后置,则寻找模式串中的一个最长前缀,
并让该前缀等于好后缀的后缀,寻找到该前缀后,让该前缀和好后缀对齐
3.模式串中没有子串匹配上好后缀,并且找不到最长前缀让该前缀等于好后缀的后缀,
此时,直接移动模式串到好后缀的下一个字符
void suffixes(char *x,int m,int *suff)
//suffix[i]=s表示以i为边界,与模式串匹配的最大长度
//P[i-s,i]==P[m-s,m]的最大长度s
{
suff[m-1]=m;
for(i=m-2;i>=0;--i)
{
q=i;
while(q>=0&&x[q]==x[m-1-i+q])
--q;
suff[i]=i-q;
}
bmGs[]表示遇到好后缀时,模式串应该移动的距离,
其中i表示好后缀前面一个字符的位置
1.模式串中有子串匹配上好后缀
2.模式串中没有子串匹配上好后缀,但找到一个最大前缀
3.模式串中没有子串匹配上好后缀,但找不到一个最大前缀
void preBmGs(char *x,int m,int bmGs[])
{
int i,j;suff[XSIZE];
suffixes(x,m,suff);
for(i=0;i<m;++i)
bmGs[i]=m;
j=0;
for(i=m-1;i>=0;--i)
if(suff[i]==i+1)
for(;j<m-1-i;++j)
if(bmGs[j]==m)
bmGs[j]=m-1-j;
for(i=0;i<=m-2;++i)
bmGs[m-1-suff[i]]=m-1-i;
}
2.栈的使用
#include
#include
#include
//栈里元素个数
#define SIZE 10
//栈的声明
struct stack{
int sta[SIZE];
int top;
};
//栈的初始化
void init_stack(struct stack* s)
{
memset(s->sta, 0, sizeof(s->sta));
s->top = -1;
}
//压栈
int in_stack(struct stack* s, int data)
{
if(s->top == SIZE-1){
printf("the stack is full. \n");
return 1;
}
(s->top)++;
s->sta[s->top] = data;
return 0;
}
//出栈
int out_stack(struct stack* s)
{
int tmp;
if(s->top < 0 ){
printf("the stack is empty. \n");
return -1;
} else {
tmp = (s->sta)[s->top];
(s->top)--;
return tmp;
}
}
int StackEmpty(struct stack* s)///判断栈空与否
{
if(s->top<0)
return 1;
else
return 0;
}
int top_stack(struct stack *s)
{
int i;
i=s->sta[s->top];
return i;
}
int IsPassed(struct stack *s,int e)
{
int i;
for(i=0;i<=(s->top);i++)
{
if(e==s->sta[i])
return 1;
}
return 0;
}
int main()
{
int i,e;
struct stack s;
init_stack(&s);
for(i=0;i<5;i++)
{
in_stack(&s,i);
}
for(i=0;i<10;i+=1)
{
int x=IsPassed(&s,i);
printf("time is %d: %d \n",i,x);
}
return 0;
}
3.利用哈弗曼树实现文件压缩
简介
给定N个权值作为N个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近。
哈夫曼静态编码
它对需要编码的数据进行两遍扫描:第一遍统计原数据中各字符出现的频率,利用得到的频率值创建哈夫曼树,并必须把树的信息保存起来,即把字符0-255(28=256)的频率值以2-4BYTES的长度顺序存储起来,(用4Bytes的长度存储频率值,频率值的表示范围为0–232-1,这已足够表示大文件中字符出现的频率了)以便解压时创建同样的哈夫曼树进行解压;第二遍则根据第一遍扫描得到的哈夫曼树进行编码,并把编码后得到的码字存储起来。
哈夫曼动态编码
动态哈夫曼编码使用一棵动态变化的哈夫曼树,对第t+1个字符的编码是根据原始数据中前t个字符得到的哈夫曼树来进行的,编码和解码使用相同的初始哈夫曼树,每处理完一个字符,编码和解码使用相同的方法修改哈夫曼树,所以没有必要为解码而保存哈夫曼树的信息。编码和解码一个字符所需的时间与该字符的编码长度成正比,所以动态哈夫曼编码可实时进行。
哈夫曼译码
在通信中,若将字符用哈夫曼编码形式发送出去,对方接收到编码后,将编码还原成字符的过程,称为哈夫曼译码。
#include
#include
#define conum 256
//哈夫曼树的节点
int counter=0,flength=0;//不重复的结点数和文件总长度
typedef struct node
{
unsigned char ch;
int w;//权值
int parent;//父节点下标
int lc;//左孩子下标
int rc;//右孩子下标
char code[conum];//节点对应的哈夫曼编码数组
}HTnode,*HT;
void initHT(HTnode ht[],int freq[]);
void createHTtree(HTnode ht[]);
void encode(HTnode ht[]);
void compress(HTnode ht[],FILE *fiPtr,FILE *foPtr);
void depress(FILE *fiPtr,FILE *foPtr);
int main()
{
//读取文件并初始化哈夫曼树
FILE *fPtr;
unsigned char ch;
int freq[conum],i,j;
char filename[conum];
printf("请输入需要压缩的文件的文件名及拓展名:\n");
gets(filename);
for(i=0;i<conum;i++)//初始化为0
{
freq[i]=0;
}
if((fPtr=fopen(filename,"rb"))==NULL)
printf("File could not be opened\n");
else
{
while(!feof(fPtr))
{
//ch=fgetc(fPtr);
fread(&ch,1,1,fPtr);
freq[ch]++;
flength++;//包括文件结束符的源文件长度
if(freq[ch]==1)
counter++;//计数在本文件中出现了多少个ascii码
//printf("ch_%c %d freq_%d\n",ch,(int)ch,freq[(int)ch]);
}
//flength--;
//printf("%d\n",flength);
HTnode ht[2*counter-1]; //建立哈夫曼节点
initHT(ht,freq);
createHTtree(ht);
encode(ht);
printf("您的压缩文件为'compress.txt',如有需要可自行转为其他格式\n");
FILE *foPtr;
foPtr=fopen("compress.txt","wb");
compress(ht,fPtr,foPtr);
fclose(foPtr);
fclose(fPtr);
printf("您的压缩文件为'depress.txt',如有需要可自行转为其他格式\n");
FILE *f3Ptr,*f4Ptr;
f3Ptr=fopen("depress.txt","wb");//解压
f4Ptr=fopen("compress.txt","rb");
depress(f4Ptr,f3Ptr);
fclose(f4Ptr);
fclose(f3Ptr);
}
return 0;
}
//初始化并存储哈夫曼节点
void initHT(HTnode ht[],int freq[])
{
int i,j;
for(i=0,j=0;i<conum;i++)//将数据权值存入哈夫曼树的节点,初始化ht数组
{
if(freq[i]!=0)
{
ht[j].ch =(unsigned char)i;
//printf("1_%d %c\n",i,ht[j].ch );
ht[j].w =freq[i];
//printf("%c,%d\n",ht[j].ch ,ht[j].w );
j++;
}
}
for(i=0;i<2*counter-1;i++)//初始化
{
ht[i].parent =0;
ht[i].lc =0;
ht[i].rc =0;
}
}
//建立哈夫曼树
void createHTtree(HTnode ht[])
{
int min1,pt1,i,j;
for (i = counter; i < 2*counter-1; i++)//构建哈夫曼树的后n-1个结点
{
min1 = 0x7FFFFFFF;//预设的最大权值,即结点出现的最大次数
for (j = 0; j < i; j++)
{
if (min1>ht[j].w &&ht[j].parent ==0)
{
pt1 = j;//min最小时的下标
min1 = ht[j].w;//min1为最小
}
}
//上面已经取出最小的,把它作为哈夫曼树的左结点,设置好相关信息
ht[i].w = ht[pt1].w;
ht[pt1].parent = i;//找到第i个结点的左孩子
ht[i].lc = pt1;//计算左分支权值大小
//printf("l_ht[pt1]=%c w_%d\n",ht[pt1].ch ,ht[i].w );
min1 = 0x7FFFFFFF;//预设的最大权值,即结点出现的最大次数
for (j = 0; j < i; j++)
{
if (min1>ht[j].w &&ht[j].parent ==0)
{
pt1 = j;//min最小时的下标
min1 = ht[j].w;//min1为最小
}
}
//上面已经取出次小的,把它作为哈夫曼树的右结点,设置好相关信息
ht[i].w += ht[pt1].w;
ht[pt1].parent = i;//找到第i个结点的右孩子
ht[i].rc = pt1;//计算右分支权值大小
//printf("ht[pt1]=%c w_%d\n",ht[pt1].ch ,ht[i].w );
}
}
//编码产生编码表
void encode(HTnode ht[])
{
int f,c,i,j;
char code[counter+1];
printf("The encoding table is as follows :\n");
for ( i = 0; i < counter; i++ )
{
c = i;
f = ht[c].parent;
j = 0;
while( f != 0 )
{//从叶子扫描到根
if ( ht[f].lc == c )
{
code[j] = '0';
}
else if(ht[f].rc == c)
{
code[j] = '1';
}
c = f;
f = ht[f].parent;
j++ ;
}
j--;
for(f=0;j>=0;j--,f++)
ht[i].code[f]=code[j];
ht[i].code[f]='\0';
printf("%c\t%s\n",ht[i].ch ,ht[i].code );
}
}
void compress(HTnode ht[],FILE *fiPtr,FILE *foPtr)
{ //压缩文件
unsigned char ch,c;
char buf[512];//定义缓冲区,保存编码
int i,j,length=12,newzo=0;//开始存储哈夫曼编码的地方,最后补的0的数量
buf[0]='\0';//初始为'\0'
fseek(fiPtr, 0, SEEK_SET);
fwrite(&flength, sizeof(int), 1, foPtr);//在压缩文件头写入源文件文件的总长度,占4个字节
fseek(foPtr, 12, SEEK_SET);//重定位压缩文件指针,从头偏移12个字节,留出空间写其他信息
while(!feof(fiPtr))
{
ch=fgetc(fiPtr);
for(i=0;i<counter;i++)
{
if(ht[i].ch==ch)//找到叶子节点,获取编码
break;
}
strcat(buf, ht[i].code);
j=strlen(buf);
c=0;
while(j>=8)//若当前编码长度大于8,需要拆分成两部分
{
for (i = 0; i < 8; i++)
{
if (buf[i] == '1')
c = (c << 1) | 1;
else
c = c << 1;
}
fwrite(&c, 1, 1, foPtr);
strcpy(buf, buf + 8);
length++;
j-=8;
c=0;
}
}
if(j>0&&j<8)//到这步留下的j一定小于8且大于0
{
while(j<8)
{
buf[j]='0';
j++;
newzo++;//记录最后补的0
}
for (i = 0; i < 8; i++)
{
if (buf[i] == '1')
c = (c << 1) | 1;
else
c = c << 1;
}
fwrite(&c, 1, 1, foPtr);
length++;
}
//写入其他信息
fseek(foPtr, 4, SEEK_SET);//移动文件指针位置到第4个字节
fwrite(&length,4,1,foPtr);//将编码的字节长度写进文件
fwrite(&newzo,4,1,foPtr);//将补的0的个数存进去
fseek(foPtr, length, SEEK_SET);//移动文件指针到压缩文件尾
fwrite(&counter,4,1,foPtr);//将编码表的元素个数存入
//写入编码表
for(i=0;i<counter;i++)
{
fwrite(&(ht[i].ch), 1, 1, foPtr);//写入每个节点的代表的字符
j=strlen(ht[i].code);
strcpy(buf, ht[i].code);
fwrite(&j, 4, 1, foPtr);//写入每个字符哈夫曼编码的长度
while(j>=8)
{
fwrite(buf,1,8,foPtr);
strcpy(buf, buf + 8);
j-=8;
}
if(j>0)//到这步留下的c一定小于8且大于0
{
while(j<8)
{
buf[j]='0';
j++;
}
fwrite(buf,1,8,foPtr);
}
}
}
void depress(FILE *fiPtr,FILE *foPtr)
{
//printf("2\n");
int flength,len,newzo,counter;//源文件长度,编码长度,补0个数,编码表的元素个数
fseek(fiPtr, 0, SEEK_SET);
fread(&flength,4,1,fiPtr);
fread(&len,4,1,fiPtr);
fread(&newzo,4,1,fiPtr);
fseek(fiPtr, len, SEEK_SET);//移动文件指针到编码表处
fread(&counter,4,1,fiPtr);
int i,c;
char buf[9];//定义缓冲区,保存编码
HTnode ht[counter];
for(i=0;i<counter;i++)
{
fread(&ht[i].ch ,1,1,fiPtr);
fread(&c,4,1,fiPtr);
//printf("1\n");
//printf("%c\n",ht[i].ch );
}
}
void HuffmanCoding(HTNode HT)//哈夫曼编码函数
{
int i,f,j;
for(i=0;i<n;i++) //哈夫曼编码
{
f=i;
HT[i].bits[0]=0; //根结点编码0
while(HT[f].parent!=-1)
{
j=f;
f=HT[f].parent;
if(HT[f].lchild==j) //左分支编码0
{
j=strlen(HT[i].bits);
memmove(HT[i].bits+1,HT[i].bits,j+1);
HT[i].bits[0]='0';
}
else //右分支编码1
{
j=strlen(HT[i].bits);
memmove(HT[i].bits+1,HT[i].bits,j+1);
HT[i].bits[0]='1';
}
}
}
for(i=0;i<256;i++)
printf("%c 's conding is %s'",i,HT[i].bits);
}
4.约瑟夫问题
问题
约瑟夫问题是个有名的问题:N个人围成一圈,从第一个开始报数,第M个将被杀掉,最后剩下一个,其余人都将被杀掉。例如N=6,M=5,被杀掉的顺序是:5,4,6,2,3。
分析:
(1)由于对于每个人只有死和活两种状态,因此可以用布尔型数组标记每个人的状态,可用true表示死,false表示活。
(2)开始时每个人都是活的,所以数组初值全部赋为false。
(3)模拟杀人过程,直到所有人都被杀死为止。
解决
int main()
{
//准备空节点和尾指针
Linklist headPtr=NULL,lastPtr=NULL;
int i,j;
headPtr=malloc(sizeof(LNode));
if(headPtr!=NULL) //判断空间是否分配成功
{
headPtr->nextPtr=headPtr;
lastPtr=headPtr;//尾指针初始指向空节点;
}
else
{
printf("List isn't created.No memory avaliable.\n'");
exit(-1);
}
//调用尾插函数建立N个节点的环形链表;
for(i=1;i<N+1;i++)
insertCirclednd2(&lastPtr,i);
printCirclelist(headPtr);
//遍历链表,第M个节点删除,到只剩下一个节点;
Linklist currentPtr,previousPtr;
currentPtr=headPtr->nextPtr;
previousPtr=headPtr;
for(j=1;j<(N-1)*M+1;j++)
{
//遇到空节点跳过
if(currentPtr==headPtr)
{
previousPtr=currentPtr;
currentPtr=currentPtr->nextPtr;
}
if(j%M==0)
{
previousPtr->nextPtr=currentPtr->nextPtr;
printf("j=%d,delete %d\n",j,currentPtr->data);
free(currentPtr);
printCirclelist(headPtr);
currentPtr-previousPtr->nextPtr;
}
else
{
previousPtr=currentPtr;
currentPtr=currentPtr>nextPtr;
}
//打印剩下的环形链表
prinCirclelist(headPtr);
//销毁链表
destroyCirclelist(&headPtr);
return 0;
}
}
void printCirclelist(Linklist headPtr)
{
Linklist currentPtr;
currentPtr=headPtr->nextPtr;
if(currentPTr==NULL)
printf("List is empty.\n");
else
{
printf("The list is:\n");
while(currentPtr!=headPtr)
{
prntf("%d-->",currentPtr->data);
currentPtr=currentPtr->nextPtr;
}
printf("end\n");
}
}
void destroyCirclelist(Linklist *headPtrPtr)
{
Linklist tempPtr,currentPtr;
currentPtr=(*headPtrPtr)->nextPtr;
while(currentPtr!=*headPtrPtr)
{
tempPtr=currentPtr;
currentPtr=currentPtr->next;
free(tempPtr);
}
free(*headPtrPtr);
//将被释放链表头指针置空
*headPtr=NULL;
}
5.链表的相关操作
#include
int main()
{
int p,q,z;
p=3;
q=2*(p++);
printf("%d %d\n",p,q);
z=2*(++p);
printf("%d %d",p,z);
return 0;
}
int LocateElem(SqList L,ElemType e)
{
i=1;
p=L.elem;
while(i<=L.length&&!equal(*p++,e))
++i;
if(i<=L.length)
return i;
else
return 0;
}
//在第pos个元素之前插入e且返回TRUE,否则返回FALSE
bool ListInsert(SqList *L,int pos,ElemType e)
{
if(pos<1||pos>L.length+1)
return FALSE;
if(L.length>=L.listsize)
return FALSE;
for(j=L.length-1;j>=pos-1;--j)
L.elem[j+1]=L.elem[j];
L.elem[pos-1]=e;
++L.length;
return TRUE;
} //平均移动数据元素次数n/2
bool ListDelete(SqList &L,int pos,ElemType &e)
{
//若1<=pos<=Listlength(L),以e带回从L中删除的
//第pos个元素且返回TRUE,否则返回FALSE;
if((pos<1)||(pos>L.length))
return FALSE;//删除位置不合法
for(j=pos;j<L.length;++j)
L.elem[j-1]=L.elem[j];
//被删除元素之后的元素左移,从后向前移动
--L.length;
return TRUE;
}//ListDelete
//时间复杂度 :O(ListLength(L));平均移动数据次数(n-1)/2
void DestroyList(SqList *L)
{
//释放顺序表L所占存储空间
free(L.elem);
L.listsize=0;
L.length=0;
} //DestroyList_Sq
//时间复杂度为:O(1)
Linklist InitList()
{
//创建带头结点的空链表,L为指向头结点的指针
L=LNode*malloc(sizeof(LNode));
if(!L)
exit(1);//存储空间分配失败
L->next=NULL;
return L;
}//InitList;
//时间复杂度为O(1)
//销毁结构操作
void DestroyList(Linklist L)
{
//销毁以L为头指针的单链表,释放链表中所有结点空间
while(L)
{
p=L;
L=L->next;
free(p);
} //while
L=NULL;//*****重要
} //DestroyList
//时间复杂度O(Listlength(L))
//链表的遍历
typedef LNode *Linklist;
status roam(Linklist L)
{
LNode *p=L;
whlie(p)
p=p->next;
return OK;
}
//求表长
int Length(Linklist L)
{
LNode *p=L;
count=0;
while(p)
{
count++;
p=p->next;
}
return count;
}
//按值查找
//在单链表L中查找值为e的结点,找到后返回其指针
LNode *LocateElem(Linklist L,Elemtype e)
{
LNode *p=L;
while(p&&(p->data!=e))
p=p->next;
return p;
}
bool GetElem(Linklist L,int pos,ElemType *e)
{
//若1<=pos<=LengthList(l),则用e带回指针L指向头结点的单链表
//中第pos个元素的值且返回函数值为TRUE,否则返回的函数值为FALSE
p=L->next;//变量初始化,p指向第一个结点
j=1;
whlie(p&&j<pos)
{
//顺结点的指针向后查找,直至p指到第pos个结点
//或p为空停止
p=p->next;
++j;
}//while
if(!p)
return FALSE;
//链表中不存在第pos个结点
*e=p->data;//取到第pos个结点
return TRUE;
}//GetElem;
//算法的时间复杂度为O(ListLength(L))
//在第pos个元素之前插入新元素e,且返回TRUE;
bool ListInsert(Linklist L,int pos,ElemType e)
{
p=L;
j=0;
while(p&&j<pos-1)
{ //查找第pos-1个结点,并令指针p指向该结点
p=p->next;
++j;
}//whlie
if(!p||j>pos-1) //参数不合法,pos<1或者>表长+1
return FALSE;
S=LNode*malloc(sizeof(LNode));
if(!s)
exit(1);//存储空间分配失败
s->data=e; //创建新元素的结点
s->next=p->next;//修改指针
p->next=s;
return TRUE;
}//listInsert
bool ListDelete(Linklist *L,int pos,ElemType *e)
{
p=L;
j=0;
while(p->next&&j<pos-1)
{
p=p->next;
++j;
}
if(!(p0->next)||j>pos-1)
return FALSE;
q=p->next;
p->next=q->next;
e=q->data;
free(q);
return TRUE;
}//listDelete_L
L=Linklist malloc(sizeof(node));
l->next= NULL;
for(i=n;i>0;i++)
{
p=Linklist malloc(sizeof(node));
if(!p)
exit(1);
p->data=A[i-1];
p->next=L->next;
L->next=p;
}
void purge_L(Linklist L)
{
//删除单链表L中的冗余元素,即操作之后的单链表中
//只保留操作之前表中所有值都不相同的元素
p=L->next;
L->next=NULL; //设新表为空表
while(p)
{
succ=p->next; //结点*p的后继
q=L->next; //q指向新表的第一个结点
while(q&&p->data!=q->data)
//在新表中查询是否存在和p->data相同的元素
q=q->next;
if(!q)//若q为空
{
p->next=L->next;
L->next=p;
}
else free(p);
p=succ;
}
}
//双向链表
typedef struct DuLNode
{
ElemType data;
struct DuLNode *prior;
struct DuLNode *next;
} DuLNode,*DuLink;
void ListInsert_Dulnode(Dulink &L,Dulnode *p,Dulnode *s)
{
s->next=p->next;
s->next->prior=s;
p->next=s;
s->prior=p;
}
void ListDelete_Dul(Dulink &L,Dunode *p,ElemType &e)
{
q=p->next;
e=p->data;
s=p->prior;
s->next=q;
q->prior=s;
free(p);
}
//循环链表
p->next=head;//判断循环是否结束
p->next==head;//判断是否为表尾结点
typedef struct node
{
Elemtype data;
struct node *pre,*next;
}Dulnode;
//pre原是空指针
//编写程序将单向链表改为双向链表
void S2D(Dulnode *L)
{
Dulnode *p=L;
while(p->next)
{
p->next->pre=p;
p=p->next;
}
}
//逆置单链表
LinkedList invert1(LinkedList head)
{
LinkedList p=head->next;
head->next=NULL;
while(p)
{
r=p->next;
p->next=head->next;
head->next=p;
p=r;
}
return (head);
}
//有头结点的单链表
LinkList LinklistSort(LinkList list)
{
p=list->next->next;//待排序的当前元素
list->sort=list->next;
while(p)
{
r=p->next;
q=list;
//寻找元素值大于待排序元素的最小结点
whlie((q->sort!=NULL&&q->sort->data<p->data))
q=q->sort;
p->sort=q->sort;
q->sort=p;
p=r;//p指向下一个待排序结点
}
}
6.栈、队列的相关操作
C语言相关
push pop
init_stack(s)
empty_stack(s)
push_stack(s,x)
pop_stack(s)
gettop_stack(S)
clear_stack(s)
current_size_stack(s)//top指针指示当前栈顶位置
typedef struct
{
Elemtype *top;
Elemtype *base;
int stacksize;
}SqStack;
//栈空: S.top=S.base ;
//此时进栈则上溢
// 栈满 : S.top=S.base+arrmax(栈的最大容量)
Status InitStack(SqStack &s)
{
s.base=(Elemtype*)malloc(100*sizeof(Eletype));
s.stacksize=100;
s.top=s.base;
return ok;
}
/*栈满 s.top-s.base>=s.stacksize
return OVERFLOW;
s.top=s.base+arrmax; */
Status Pop(SqStack &s,Elemtype &e)
{
if(s.top==s.base)
return errror;
else
e=*--(s.top);
return ok;
}
status GetTop(SqStack s,Elemtype &e)
{
if(s.top==s.base)
return error;
else
e=*(s.top-1);
return ok;
}
void conversion()
{
InitStack(S);
cin>>N;
while(N)
{
Push(S,N%8);
N=N/8;
}
while(!StackEmpty())
{
Pos(S,e);
cout<<e;
}
}
OPTR--运算符 OPND --寄存数
compute()
{
init_stack(OPTR);//运算符
init_stack(OPND);
push(OPTR,'#');
w=getchar();
while(w!'#'||gettop(OPTR)!='#')
{
if(w为整数)
{
push(OPND,w);
w=getchar();
}
else
{
}
}
}
void face(int n,int &f)
{
InitStack(S);
while(n!=0)
{
Push(S,n);
n-=1;
}
f=1;
whlie(!StackEmpty(S))
{
Pop(S,n);
f=n*f;
}
}
init_queue(q)
empty_queue(q)
en_queue(q,x) //入队
dl_queue(q) //出队
gethead_queue(q)
clear_queue(q)
current_size_queue(q)
typedef struct node
{
Elemtype data;
struct node *next;
}QNode;
QNode *front,*rear;
typedef struct
{
QNode *front;
QNode *rear;
}LinkQueue;
Status InitQueue (LinkQueue *Q)
{
Q->front=Q->rear=NULL;//链队不带头结点
return OK;
}
//入链队
Status EnQueue(LinkQueue *Q,Elemtype e)
{
s=(Qnode*)malloc(sizeof(Qnode));
s->data=e;
s->next=NULL:
Q->rear->next=s;
Q->rear=s;
return OK;//不是将rear隔过去了吗
}
q.base+q.rear=e;
q.rear=(q.rear+1)%MAX
q.front==q.rear
*e=*(q.base+q.front)
q.front=(q.front+1)%MAX;
strlength(s)
strassign(*s1,s2)
strconcat(*T,s1,s2)
strcompare(s1,s2)
substring(*sub,s,pos,len)
index(s1,s2,pos)
for(li=0;i<s1[0];i++)
if(s1[i]!=s2[i])
return FALSE;
return OK;
for(i=0;i<=len;i++)
{
sub[i]=s[pos+i-1];
sub[0]=len;
}
typedef struct node
{
char data;
struct ndoe *next;
}
i=pos;j=1;
while(i<=S[0]||S[o])
void get_nextval(SSring &T,int &nextval[])
{
i=1;
nextval[1]=0;
j=0;
if(j==0||T[i]==T[j])
{
++i;++j;
}
if(T[i]!=T[j])
{
nextval[i]=j;
}
else
{
nextval[i]=nextval[j];
}
Cpp相关
#include
#include
#include
#define ERROR -1
typedef int ElementType
typedef enum
{
push,pop,end
} Operation;
typedef int Position;
typedef struct Snode *Ptr;
struct Snode
{
ElementType *Data; //存储元素数组
Position Top; //栈顶指针
int MaxSize; //堆栈最大容量
}
typedef Ptr Stack;
//初始化栈
Stack CreateStack(int MaxSize)
{
//准备存放结构体型的变量数据
Stack S =(Stack)malloc(sizeof(struct Snode));
//动态申请数组空间
S->Data=(ElementType *)malloc(MaxSize* sizeof(ElementType));
//把栈顶指针指向0
S->Top=0;
//给MaxSize赋值
S->MaxSize=MaxSize;
return S;
}
//入栈
bool Push(Stack S,ElementType X)
{
//判断栈顶是否与栈容量相等
if(S->MaxSize==S->Top)
{
//输出Stack Full
puts("Stack Full");
return 0;
}
//不相等则栈顶指针+1
S->Data[S->Top++]=X;
return 1;
}
//出栈
ElementType Pop(Stack S)
{
//判断栈顶是否为空
if(!S->Top)
{
//输出Stack Empty
puts("Stack Empty");
//返回ERROR
return ERROR;
}
//返回栈顶元素
return S->Data[--S->Top];
}
Operation GetOp()
{
//定义字符数组a
char a[11];
scanf("%s",a);
if(!strcmp("Push",a))
return push;
if(!strcmp("Pop",a))
return pop;
if(!strcmp("End",a))
return end;
}
//打印栈内元素
void PrintStack(Stack S)
{
while(S->Top)
printf("%d",S->Data[--S->Top]);
puts("");
}
int main()
{
ElementType X;
Stack S;
int N,done =0;
//接受栈容量
scanf("%d",&N);
//把栈初始化
S=CreateStrack(N);
// 循环操作栈,知道done=1
while(!done)
{
switch(GetOp())
{
case push:scanf("%d",&X);Push(S,X);break;//入栈
case pop:X=Pop(S);//出栈
if(X!=ERROR)
printf("%d is out\n",X);
case end:PrintStack(S);done=1;break;//结束程序,打印栈内元素。
}
}//while
return 0;
}//main
7.树的相关操作
pre_find(bitree bt,elemtp x,bitree q)
{
if(!bt&&(F==false))
{
if(bt->data==x)
{
q=bt;
F=true;
}
}
else
{
pre_find(bt->lc,x,q);
pre_find(bt->rc,x,q);
}
}
pre_level(bitree p,int level)
{
if(!p)
{
write(p->data,level);
pre_level(p->lc,level+1);
pre_level(p->rc,level+1);
}
}
pre_copy(bitree bt,bitree &q)
{
if(bt!=null)
{
new(q); //new()应该是赋予空间
q->data=bt->data;
pre_copy(bt->lc,q->lc);
pre_copy(bt->lc,q->lc);
}
else
{
q=NULL;
}
}
//哈夫曼编码树
typedef struct
{
unsigned int weight;
unsigned int parent,lch,rch;
} HTNode;
typedef HTNode huffmantree[m];
huffmantree ht;
int search(int a[],int x)
{
int low,mid,high;
low=1;
high=n;
while(low<=high)
{
mid=(low+high)/2;
if(x<a[mid])
high=mid-1;
else if(x>a[mid])
low=mid+1;
else
return mid;
}
return 0;
}
status insertbst(bitree &t,elemtype e)
{
if(!search(t,e.key,null,p))
{
s=(bitree)malloc(sizeof(bitnode));
s->data=e;
s->lchild=s->rchild=null;
if(!t) //二叉树为空
t=s;
else if LT(e.key,p->data.key) 如果e.key小于p->data.key
p->lchild=s;
else
p->lchild=s;
return true;
}//insertbst
}