数据结构的一些算法

内容
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
	
}
   

你可能感兴趣的:(数据结构,算法,链表)