数据结构小结.docx
- 文档编号:5394550
- 上传时间:2022-12-15
- 格式:DOCX
- 页数:52
- 大小:32.75KB
数据结构小结.docx
《数据结构小结.docx》由会员分享,可在线阅读,更多相关《数据结构小结.docx(52页珍藏版)》请在冰豆网上搜索。
数据结构小结
线性表
1.栈
栈的定义
typedefstruct
{
ElemTypes[Maxsize];
Inttop;
}stack;
栈的压入push(ST,x)
将整数x插入到ST栈中的函数如下:
voidpush(ST,x)
stack*ST;
ElemTypex;
{
if(ST->top==Maxsize-1)printf(“栈上溢出!
\n”);/*若栈满则显示相应信息*/
else/*否则栈指针top增1,将x附给栈顶的元素*/
{
ST->top++;
ST->s[ST->top]=x;
}
}
栈的弹出pop(ST)
从栈中弹出栈顶元素的函数如下:
voidpop(ST)
stack*ST;
{
if(ST->top==0)/*若栈空则显示相应信息*/
printf(“栈下溢出!
\n”);
else
ST->top--;/*否则栈指针减1,即栈顶为下一个元素*/
}
读取栈顶元素top(ST,x)
读取栈顶元素而保持栈不变的函数如下:
voidtop(ST,x)
stack*ST;
ElemType*x;
{
if(ST->top==0)
printf(“无栈顶元素!
\n”);/*若栈为空则显示相应信息*/
else
*x=ST->s[ST->top];
}
判定栈是否为空sempty(ST)
判定栈是否为空的函数如下:
intsempty(ST)
stack*ST;
{
if(ST->top==0)return
(1);/*若栈为空则返回true*/
elsereturn(0);/*否则返回false*/
}
取栈顶元素ptop(ST)
从栈中取出栈顶元素并从栈中删除该栈顶元素的函数如下:
ElemTypeptop(ST)
Stack*ST
{
top(ST,x);/*将栈顶元素附给x*/
pop(ST);/*将栈顶元素弹出*/
return(x);/*返回x值*/
}
队列
队列的存储方式
假设队列的元素个数最大不超过整数Maxsize,所有的元素都具有同一数据类型ElemType,则可用下列方式来定义队列类型queue;
typedefstruct
{
ElemTypeq[Maxsize];
Intfront,rear;
}queue;
循环队列的入队enq(QU,x)
将整数x插入到QU队列中的函数如下:
voidenq(QU,x)
queue*QU;
ElemTypex;
{
if((QU->rear+1))%Maxsize==QU->front)printf(“队列上益处!
\n”);
else
{
QU-.rear=(QU->rear+1)%Maxsize;
QU->q[QU->rear]=x;
}
}
循环队列的出队deq(QU,x)
一个QU队列的尾部元素出队的函数如下:
voiddeq(QU,x)
queue*QU;
ElemType*x;
{
if(QU->front==QU->rear)printf(“队列下益处!
\n”);
else
{
QU->front=(QU->front+1`)%Maxsize;
xx=QU->q[QU->front];
}
}
读取循环队列的头元素gethead(QU,x)
读取队列QU的队列头元素的函数如下:
voidgethead(QU,x)
queue*QU
ElemType*x;
{
if(QU->front==QU->rear)printf(“队列下益出”);
else*x=QU->q[(QU->front+1)%Maxsize];
}
链表
单链表的存储结构:
单链表的结点的类型node的定义如下:
typedefstructlinknode
{
ElemTypedata;
Structlinknode*next;
}node;
这里的ElemType可以是任何相应的数据类型如int,float或char等,在算法中,我们规定ElemType默认是int类型。
建立一个单链表
输入一系列整数,以0标志结束,将这些整数作为data域建立一个单链表的函数如下:
voidcreat()
{
node*head,p,*s;
intx,cycle=1;/*cycle是循环控制变量*/
head=(node*)malloc(sizeof(node));/*建立头结点,由head所指向*/
p=head;
while(cycle)
{
scanf(“%d”,&x);
if(x!
=0)
{
s=(node*)malloc(sizeof(node));/*建立下一个节点*/
s->data=x;
p->next=s;
p=s;
}
elsecycle=0;
}
p->next=NULL;
p=head;
head=head->next;/*删除头结点*/
free(p);
}
查找某个结点
在已建立好的单链表(表头指针为head)中查找元素值为x的函数如下:
voidfind(head,x)
node*head;
ElemTypex;
{
node*p;
p=head;
while(p!
=NULL&&p->data!
=x)p=p->next;
if(p!
=NULL)
printf(“结点找到了!
\n”);
else
printf(“结点未找到!
\n”);
}
在循环单链表中查找某个结点的函数如下:
voidfind1(head,x)
node*head;
ElemTypex;
{
node*p;
if(head->data==x)
printf(“结点找到了!
\n”);
else
{
p=head->next;
while(p->data!
=x&&p!
=head)p=p->next;
if(p!
=head)
printf(“结点找到了!
\n”);
else
printf(“结点未找到!
\n”);
}
}
求单链表的长度
计算一个已建立好的单链表(表头指针为head)的结点个数的函数如下:
intlength(head)
node*head;
{
intn=0;
node*p;
p=head;
while(p!
=NULL)
{
p=p->next;
n++;
}
return(n);
}
求一个循环单链表的长度的函数如下:
intlength(head)
node*head;
{
node*p;
intn=0;
if(head==NULL)n=0;
else
{
p=head->next;
n=1;
while(p!
=head)
{
p=p->next;
n++;
}
}
return(n);
}
在单链表中插入一个结点
在单链表中第iI个节点(i>=0,i=0表示插入的结点作为第一个节点)之后插入一个元素为
x的结点的函数如下:
voidinsert(head,i,x)
node*head;
inti;
ElemTypex;
{
node*s,*p;
intj;
s=(node)malloc(sizeof(node));/*建立一个待插入的结点*/
s->data=x;
if(i==0)/*如果i=0,则将s所指结点作为表头*/
{
s->next=head;
head=s;
}
else
{
p=head;j=1;/*在单链表中查找第i个节点,由p所指向*/
while(p!
=NULL&&j
{
j++;
p=p->next;
}
if(p!
=NULL)/*若查找成功,则把s插入到其后*/
{
s->next=p->next;
p->next=s;
}
else
printf(“未找到!
\n”);
}
}
从单链表中删除一个结点
从单链表中删除一个其值等于给定值X的结点的函数如下:
voiddelete(head,x)
node*head;
ElemTypex;
{
node*p,*q;
if(head==NULL)printf(“链表下溢”);/*如果单链表为空,则下溢处理*/
if(head->data==x)/*如果表头结点为被删结点,则删除之*/
{
p=head;
head=head->next;
free(p);
}
else
{
q=head;p=head->next;/*从第2个节点开始查找其值为x的结点*/
while(p!
=NULL&&p->data!
=x)
if(p->data!
=x)
{
q=p;p=p->next;
}
if(p!
=NULL)
{
q->next=p->next;
free(p);
}
else
printf(“未找到!
\n”);
}
}
双链表
双链表的定义
双链表中结点的类型定义为:
typedefstructlinknode
{
ElemTypedata;
structlinknode*left,*right;
}dnode;
这里的ElemType可以是任何相应的数据类型如int,float或char等,在算法中,我们规定ElemType默认是int类型
建立一个双链表
输入一系列整数,以0标志结束,将这些整数作为data域建立一个双链表的函数如下:
voidcreat()
{
dnode*head,*p,*s;
intcycle=1;
head=(node*)malloc(sizeof(dnode));
p=head;
while(cycle)
{
scanf(`”%d”,&x);
if(x!
=0)
{
s=(node)malloc(sizeof(dnode));/*建立下一个结点,由S所指向*/
s->data=x;
p->right=s;
s->left=p;
p=s;
}
elsecycle=0;
}
head=head->right;/*删除头结点*/
head->left=NULL;/*将最后一个结点的left域置为NULL*/
p->right=NULL;/*将第一个结点的right域置为NULL*/
}
如果需要生成循环双链表,只需要把上叙函数creat()中最后的两个语句:
head->left=NULL;
p->right=NULL;
改为:
head->left=p;/*这里p指向最后一个结点*/
p->right=head;
查找某个结点
在已经建立好的双链表(表头指针为head)中查找元素值为x的函数如下:
voidfind(head,x)
dnode*head;
intx;
{
dnode*p;
p=head;
while(p!
=NULL&&p->data!
=x)p=p->next;
if(p!
=NULL)
printf(“终点找到了!
\n”);
else
printf(“终点未找到!
\n”);
}
在循环双链表中查找某个结点的函数如下:
voidfind1(VARhead:
dnode,VARx:
integer)
dnode*head;
intx;
{
dnode*p;
if(head->data==x)/*若头结点为要找的结点,则显示相应信息并返回*/
printf(“终于找到了!
\n”);
else/*否则查找该结点*/
{
p=head->right;
while(p->data!
=x&&p!
-head)p=p->right;/*p=p->right也可改为p=p->right*/
if(p!
=head)
printf(“结点找到了!
\n”);
else
printf(“未找到!
\n”);
}
}
在双链表中插入一个结点
在双链表中第I个结点(i>=0,i=0时表示插入表头结点)之后插入一个元素为x的结点的函数如下:
voidinsert(head,I,x)
dnode*head;
intI;
ElemTypex;
{
dnode*s,*p;
intj;
s=(dnode)malloc(sizeof(dnode));/*建立一个待插入的结点,由s指向*/
s->data=x;
if(I==0)/*如果i=0,则将s所指结点插入到表头后返回*/
{
s->right=head;
head->left=s;
head=s;
head->left=NULL;
}
else
{
p=head;j=1;/*在双链表中查找第I个结点,由p所指向*/
while(p!
=NULL&&j
{
j++;
p=p->righr;
}
if(p!
=NULL)/*若查找成功,则把s插入到p之后*/
if(p->right==NULL)/*若p是最后一个结点,则直接把s链接起来*/
{
p->right=s;
s->right=NULL;
s->left=p;
}
else
{
s->right=p->right;
p->right->left=s;
p->right=s;
s->left=p;
}
else
printf(“未找到!
\n”);
}
}
从双链表中删除一个结点
从双链表中删除一个其值等于给定值x的结点的函数如下:
voiddelete(head,x)
dnode*head;
ElemTypex;
{
dnode*p;
if(head==NULL)printf(“链表下溢!
\n”);/*如果双链表为空,则下溢处理*/
if(head->data==x)/*如果表头结点值等于x,则删除之*/
{
p=head;
head=head->right;
head->left=NULL;
free(p);
}
else
{
p=head->right;/*从第二个结点开始查找其值为x的结点*/
while(p!
=NULL&&p->data!
=x)
if(p->data!
=x)/*在查找时,p指向该结点*/
p=p->right;
if(p!
=NULL)/*若找到了该结点,则进行删除处理*/
if(p->right==NULL)/*若p所指结点是最后一个结点,则直接删除之*/
{
p->left->right=p->right;
free(p);
}
else/*若p所指结点不是最后一个结点,则把p的左右两个结点联结起来*/
{
p->left->right=p->right;
p->right->left=p->left;
free(p);
}
else/*未找到时,显示相应信息*/
printf(“未找到!
\n”);
}
}
串
串的模式匹配算法
求子串的定位函数Index(S,T,Pos)
intIndex(SStringS,SStringT,intpos){
//返回子串T在主串S中第POS个字符之后的位置。
若不存在,则函数值为0
//其中,T非空,1<=pos<=StrLength(S)
I=pos;j=1;
While(I<=s[0]&&j<=T[0]){
If(S[i]==T[j]){++I;++j;}//继续比较后续字符
Else{I=I-j+2;j=1;}//指针后退重新开始匹配
}
if(j>T[0])returnI-T[0];
elsereturn0;
}//index
KMP算法
IntIndex_KMP(SStringS,SStringT,intpos)
//利用模式串T的next函数求T在主串S中第pos个字符之后的位置的KMP算法。
其中,T非空,1<=pos<=StrLength(s).
I=pos;j=1;
While(I<=s[0]&&j<=T[0]){
If(j==0||S[i]==T[j]){++I;++j;}//继续比较后续字符
Elsej=next[j];//模式串向右移动
}
if(j>T[0])returnI-T[0];//匹配成功
elsereturn0;
}//Index_KMP
求模式串的next函数
voidget_next(SStringT,int&next[])
{
//求模式串T的next函数值并存入数组next
I=1;next[1]=0;j=0;
While(I { If(j==0||T[i]==T[j]) { ++I; ++j; next[i]=j; } Elsej=next[j]; } }//get_next 改进后的next函数 voidget_next(SStringT,int&next[]) { //求模式串T的next函数修正值并存入数组nextval I=1;next[1]=0;j=0; While(I { If(j==0||T[i]==T[j]) { ++I; ++j; if(T[i]! =T[j])nextval[i]=j; elsenextval[i]=nextval[j]; } Elsej=nextval[j]; } }//get_next 顺序存储及其基本运算 顺序存储采用一般线性表的存储结构来定义串的类型: typedefstruct { charvec[Maxsize]; intlen; }orderstring; 其中vec域用来存储字符串,len域用来存储字符串的当前长度,Maxsize常量表示允许所存储字符串的最大长度。 例如,用一下语句定义Maxsize为100: #defineMaxsize100 以顺序方式存储串的基本运算如下: 链接两个串 两个串r1和r2首位相连成一个串r,其中r1在前,r2在后, orderstring*concat(r1,r2) orderstring*r1,*r2; { intI; orderstring*r; printf(“*r1=%s,r2=%s\n”,r1->vec.r2->vec); if(r1->len+r2->len>m0)/*若两串长度之和大于m0,则进行溢出处理*/ printf(“上溢出! \n”); else { for(I=0;I r->vec[i]=r1->vec[i]; for(I=0;I r->vec[r1->len+i]=r2->vec[i]; r->vec[r1->len+i]=’\0’;/*最后一个位置附给’\0’*/ r->len=r1->r1->len+r2->len;/*r串长度等于两串长度之和*/ } return(r); } 取子串 从串r1中的第I个字符开始,把连续j个字符组成的子串赋给r orderstring*substring(r1,I,j) orderstring*r1; intI,j; { intk; orderstring*r; if(I+j-1>r1->len)/*若I,j的值超出允许的范围,则进行‘超界’处理*/ printf(“超界! \n”); else { for(k=0;k r->vec[k]=r1-vec[I+k-1]; r->len=j; r->vec[r->len]=’\0’; } return(r); } } 删除子串 从串r中删除从第I个字符开始的,长度为j的一个子串 orderstring*delsubstring(r,I,j) orderstring*r; intI,j; { intk; if(I+j-1>r->len)/*若I,j的值超出允许的范围,则进行超界处理*/ printf(“超界! \n”); else { for(k=I+j-1;k r->vec[k-j]=r->vec[k]; r->len=r->len-j; r->vec[r->len]=’\0’; } return(r); } 插入子串 把串r1插入到串r中第I个字符开始的位置上。 Orderstring*insert(r,r1,i) Orderstring*r,*r1; IntI; { intk; if(I>=len||r->len+r1->len>m0)printf(“不能插入! \n”); else { for(k=r->len-1;k>=I;k--)/*从第I个位子起空出连续r1->len个位子*/ r->vec[r1->len+k]=r->vec[k]; for(k=0;k r->vec[I+k-1]=r1->vec[k]; r->len=r->len+r1->len; r->vec[r->len]=’\0’; } return(r); } 求子串位置 求子串位置的运算又叫做串的模式匹配运算。 从串r1中求出首次与r2相同的子串的起始位置,若r1中不存在r2,则返回0 intposition(r1,r) orderstring*r1,*r; { intI,j,k; for(I=0;r->vec[i];I++) for(j=I,k=0;r->vec[j]=r1->vec[k];j++,k++) if(! r1->vec[k+1])/*子串结尾,表示查找成功*/ return(i); return(-1);/*未找到子串*/ } 数组和稀疏矩阵(略) 递归 编写一个过程采用非递归方法计算一棵二叉树的所有结点个数。 先定义如下常量和变量类型: #definestructnode typestructnode { chardata; structnode*left,*right; }bitree; 计算一棵二叉树的所有结点个数的counter函数如下: intcounter(bitree*t)
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 小结