19、设计一个带头结点的循环单链表,其结点值为正整数,设计算法反复找出链表内最小值并不断输出,并将结点从链表中删除,直到链表为空,再删除表头节点。
整体循环链表结束条件:L->next=L;
每趟找出最小值结束条件:p->next=L;
void delMinVal(LinkList &L){
LNode *p,*pre;
LNode *minp,*minpre;
while(L->next!=L){
pre=L;
p=L->next;
minpre=L;
minp=L->next;
while(p!=L){
if(p->data<=minp->data){
minp=p;
preminp=pre;
}
pre=p;
p=p->next;
}
printf("%d\n",minp->data);
preminp->next=minp->next;
free(minp);
}
free(L);
}
20、判断单链表是否有环
设置快慢指针,fast与slow指针,每次slow指针移动一次,fast指针移动两次,当有环时,fast与slow必然会相遇,即fast=slow。
bool isLoop(LinkList L){
LNode *fast,*slow;
if(L){
slow=L,fast=L;
while(slow->next && fast->next){
slow=slow->next;
fast=fast->next->next;
if(slow==fast){
return true;
}
}
return false;
}
return false;
}
21、给定一个单链表L(a1,a2,a3,....,an),将其重新排列为L(a1,an,a2,an-1,.....)
1、找出单链表的中间位置,可利用快慢指针,当fast指针指向链尾时,slow刚好指向中间位置
2、逆置表的后半部分
3、从前后两端依次各取一个结点进行重新排列
void change_list(LinkList &L){
LNode *fast,*slow;
LNode *p,*q;
fast=slow=L;
//寻找中间结点
while(fast->next){
slow=slow->next;
fast=fast->next;
if(fast->next) fast=fast->next;
}//运行完毕后,slow指向的是链表的中间元素
//将后半表结点逆置
q=slow->next,slow->next=NULL;
while(q){
r=q->next;
q->next=slow->next;
slow->next=q;
q=r;
}
//将后半表插入前半表
p=slow->next;s=L->next;
slow->next=NULL;
while(p){
r=p->next;
p->next=s->next;
s->next=p;
s=p->next;
p=r;
}
}
三、栈、队列、字符串
1、Q是一个队列,S是一个空栈,编写算法使得队列中元素逆置
先将Q中的元素出队列依次入栈,再将栈中元素全部依次出栈入队列
void Reverse(Stack &S,Queue &Q){
while(!QueueEmpty(Q)){
x=DeQueue(Q);
Push(S,x);
}
while(!StackEmpty(S)){
Pop(S,x);
EnQueue(Q,x);
}
}
2、利用栈来判断单链表的全部n个字符是否中心对称
先让表中前半部分入栈,然后每次弹出栈与后半部分结点的值进行比较
int dc(LinkList L,int n){
char s[n/2];
LNode *p=L->next;
for(int i=0;i<n/2;i++){
s[i]=p->data;
p=p->data;
}
i--;
if(n%2==1){
p=p->next;
}
while(p && p->data==s[i]){
p=p->next;
i--;
}
if(i==-1)
return 1;
else
return 0;
}
3、判断一个表达式中括号是否配对
遇到左括号则入栈,碰到右括号判断类型是否匹配,匹配则继续进行,不匹配则直接停止,遍历结束后,栈为空则成功
bool bracketCheck(char str[],int len){
SqStack S;
InitStack(S);
for(int i=0;i<len;i++){
if(str[i]=='[' || str[i]=='(' || str[i]=='{')
Push(S,str[i]);
else{
if(StackEmpty(S)) return false;
char topElem;
Pop(S,topElem);
if(str[i]==')' && topElem !='(')
return false;
if(str[i]==']' && topElem !='[')
return false;
if(str[i]=='}' && topElem !='{')
return false;
}
}
return true;
}
4、假设一个序列为HSSHHHS,运用栈的知识,编写算法将S全部提到H之前,即为SSSHHHH
将序列字符为H的依次入栈,S重新进入序列,遍历完成后将栈中元素弹出加入序列中
void Ajust(char A[],int n){
int j=0;
SqStack S;
InitStack(S);
for(int i=0;i<n,i++){
if(A[i]=='H'){
Push(S,A[i]);
}
else{
A[j]=A[i];
j++;
}
}
while(!StackEmpty(S)){
Pop(S,A[j]);
j++;
}
}
本文介绍了链表操作的几个实例,包括删除循环链表中的最小元素直至链表为空,判断单链表是否有环,以及重新排列链表。此外,还探讨了栈和队列的应用,如队列元素的逆置,单链表的中心对称性检查,以及括号匹配的判断。这些算法深入展示了数据结构在实际问题中的应用。
1077

被折叠的 条评论
为什么被折叠?



