数据结构算法整理讲解
第四章串
串的动态存储方式采用链式存储结构和堆存储结构两种形式
//串的动态存储结构——块链存储类型定义
#define CHUNKSIZE <用户定义的结点大小>;
typedef struct chunk----------结点结构
{ char ch[CHUNKSIZE];
struct chunk *next;
}chunk
typedef struct
{ chunk *head,*tail;---------尾指针指示链表中的最后一个结点
int length;--------串的长度
}
//串的动态存储结构——堆结构
char store[maxsize];
typedef struct string
{
int length,*stadr;
/ *length域指示串序列的长度stadr域指示串序列的store中的起始地址*/ };
//串基本操作的实现——串的模式匹配(求子串位置)
int Index_bf(strtp s,t);
{/*Brute-Force算法思想求模式串t在主串s中的定位函数*/
i=1;
j=1; /*指针初始化*/
while ((i<=s.curlen)&&(j<=t.curlen))
{if(s.ch[i]==t.ch[j])
{i+1; j=j+1;} /*继续比较后继字符*/
else{i=i-j+2; j=1;}; /*指针后退重新开始匹配*/
if(j>t.curlen ) return i-t.curlen;
else return 0;
};/*Index_bf*/
//串的简单应用——统计字母出现频率
letter_Frequency(strtp text)
{/*统计给定文本text中每个字母出现的频率*/
char alph[]='abcdefghijklmnopqrstuvwxyz';
int freq[26];
total=0;
n=len(text);
1
for(i=0;i<26;i++)freq[i]=0;/*freq为数组*/
for(i=0;i {ch=SubStr(text,i,1); j=Index(alph,ch); if(j>0) {freq[j]=freq[j]+1; total=total+1; }; } for(i=0;i<26;i++) {freq[i]=freq[i]/total; printf(‘%f’,freq[i]); } }; /*Letter_Frequency*/ 第五章数组 //稀疏矩阵的三元组表示法: #define MAX 10 typedef struct {int i,j; elemtype v; }node; typedef struct {int mu,nu,tu; node data[MAX]; }mat; //稀疏矩阵的转置运算的实现 mat *zzjz(mat *a) {int am.bn.col; mat *b; /*转置后的矩阵b*/ b=(mat *)malloc(sizeof(mat)); b.nu=a.mu; b.mu=a.nu; b.tu=a.tu; /*a,b矩阵行、列交换*/ bn=0; for (col=1;col<=a.nu;col++) /*按a的列序转置*/ for(am=1;am<=a.tu;am++) /*扫描整个三元组表*/ if(a.data[am].j==col) /*列号为col是转置*/ {b.data[bn].i=a.data[am].j; b.data[bn].j=a.data[am].i; b.data[bn].v=a.data[am].v; bn++; /*b.data中的结点序号加1*/ } return b; /*返回转置矩阵的指针*/ 2 } //十字链表的结点类型定义如下: typedef struct node {int i,j,v; struct node *down,*right; }szjd; //十字链表的建立表示法 szlbcreate(szjd *m[ ],szjd *n[ ],int *hs,int *ls) {int x,y,z,ms,ns; int k=0; szjd *p,*q,*s; ms=ns=0; scanf(“%d,%d”,&ms,&ns); for(k=0;k m[k]=NULL; for(;k n[k]=NULL; *hs=ms; *ls=ns; for ( ; ;) {scanf(%d,%d,%d”,&x,&y,&z); if (x==0||y==0) break; if((x>ms)||(y>ns)) continue; s=(szjd*)malloc(sizeof(szjd)); s->i=x;s->j=y;s->v=z; s->right=s->down=NULL; q=NULL; p=m[x-1]; while((p!=NULL)&&(y>p->j)) {q=p;p=p->right;} if (p==NULL) {if(q==NULL) m[x-1]=s; else q->right=s;} else if(y==p->j) {p->v=z;free(s);continue;} else {s->right=p;q->right=s;} q=NULL; p=n[y-1]; while((p!=NULL)&&(x>p->i)) {q=p; p=p->down;} 3 if (p==NULL) if (q==NULL) n[y-1]=s; else q->down=s; else {s->down=p;q->down=s;} } } 第六章树 //二叉链表的类型定义: struct bnodept { elemtype data; struct bnodept *lchild,*rchild } typedef struct bnodept *bitreptr; //遍历的递归算法的类型定义 struct bnodept { datatype data; struct bnodept *lchild,*rchild } //先根遍历的递归算法 void preorder(bitreptr t) //按先根次序遍历二叉树T,T的每个根结点有三个域:lchild,data,rchild { if (t!=NULL) //为非空二叉树 { visite(t->data); //访问根结点 preorder(t->lchild); //先根遍历左子树 preorder(t->rchild); //先根遍历右子树 } } // void preorder(JD *bt) { if(bt!=NULL) { printf("%d\t",bt->data); preorder(bt->lchild); preorder(bt->rchild); } } //中根遍历的递归算法 4 void inorder(bitreptr t)//按中根次序遍历二叉树t,t的每个结点有三个域:lchild,data,rchild { if (t!=NULL) { inorder(t->lchild); visite(t->data); inorder(t->rchild); } } //后根遍历的递归算法 void postorder(bitreptr t) //按后根次序遍历二叉树t,t的每个结点有三个域:lchild,data,rchild { if (t!=NULL) { postorder(t->lchild); postorder(t->rchild); visite(t->data); } } //先根序遍历的非递归算法 void preorder(bitreptr t) {bitreptr stack[MAX+1]; //顺序栈 int top=0; //栈顶指针 do { while (t!=NULL) {visite(t->data); //访问根结点 if (top==MAX) //栈已满 {printf(“stack full”); return; //不能再遍历下去 } stack[++top]=t; //根指针进栈 t=t->lchild; //移向左子树 } if (top!=0) //栈中还有根指针 {t=stack[top--]; //取出根指针 t=t->rchild; //移向右子树 } } while (top!=0||t!=NULL); //栈非空或为非空子树 } //中根序遍历的非递归算法 void inorder(JD *bt) { int i=0; JD *p,*s[M]; p=bt; 5 { while(p!=NULL) { s[i++]=p; p=p->lchild; } if(i>0) { p=s[--i]; printf("%d\t",p->data); p=p->rchild; } }while(i>0||p!=NULL); } //二叉树中以值为x的结点为根的子树深度 int Get_Sub_Depth(bitreptr T, datatype x)//求二叉树中以值为x的结点为根的子树深度{ if(T->data==x) { printf("%d\n",Get_Depth(T)); //找到了值为x的结点,求其深度 exit 1;} else { if(T->lchild) Get_Sub_Depth(T->lchild,x); if(T->rchild) Get_Sub_Depth(T->rchild,x); //在左右子树中继续寻找 } }//Get_Sub_Depth // int Get_Depth(bitreptr T) //求子树深度的递归算法 { if(!T) return 0; else { m=Get_Depth(T->lchild); n=Get_Depth(T->rchild); return (m>n?m:n)+1; } }//Get_Depth //在二叉树中求指定结点的层数。 int preorder(bitreptr root,datatype ch)//在二叉树root中求值为ch的结点所在的层数{ int lev,m,n; if (root==NULL) lev=0;//空树 6 if (root->data==ch) lev=1;//ch所在结点为根结点 else { m=preorder(root->lchild,ch);//在左子树中查找ch所在结点 n=preorder(root->rchild,ch); //在右子树中查找ch所在结点 if (m==0&&n==0) lev=0; //在左右子树中查找失败 else lev=((m>n)?m:n)+1;//在左子树或右子树中查找成功时,层数加1 } return(lev); } //按先序序列建立二叉树的二叉链表。 bitreptr crt_bt_pre( ) //按先序序列建立二叉树的二叉链表。函数的返回值指向根结点 { char ch; bitreptr bt; ch=getchar();//从键盘上输入一个字符 if (ch==' ') return(NULL);//空格作为结束标志 else { bt=(bitreptr)malloc(sizeof(struct bnodept));//产生新结点 bt->data=ch; bt->lchild= crt_bt_pre(); bt->rchild= crt_bt_pre(); return (bt); } } //求二叉树的叶子数 int countleaf( bitreptr root) //先根遍历根指针为root的二叉树以计算其叶子数 { int i; if(root==NULL) i=0; else if((root->lchild==NULL)&&(root->rchild==NULL)) i=1; else i=count2(root->lchild)+count2(root->rchild); return(i); } //二叉树中根序线索化 Typedef enum {link,thread} pointertag;//枚举值link和thread分别为0,1 7