目录
5.利用栈和队列实现队列中元素逆置(Q是一个队列,S是一个空栈)
一.顺序表的逆置
1.设计一个高效的算法,将顺序表L中的所有元素逆置
思想:
扫描顺序表L的前半部分元素,对于元素L.data[i](0<=i<L.length/2)
将其与后半部分对应元素L.data[L.length-i-1]进行交换
代码:
void Reverse(SqList &L)
{
int temp;//辅助变量
for(i=0;i<L.length/2;i++)
{
temp=L.data[i];//交换
L.data[i]=L.data[L.length-1];
L.data[length-i-1]=temp;
}
}
2.已知在一维数组A[m+n]中依次存放两个线性表(a1,a2,...am)和(b1,b2,...bn)尝试编写一个函数将数组中两个顺序表的位置互换,即将(b1,b2,...bn)放在(a1,a2...am)的前面
思想:
(1)先将数组A[m+n]的全部元素原地逆置为(bn,bn-1,...........b1,am,am-1,.......a1)
(2)再对前n 个元素和后m个元素分别使用逆置算法,即可得到(b1,...bn,a1,....an)
代码:
void Reverse(int A[],int left,int right ,int arraysize)
{ //left和right 对应数组下标,arraysize 为数组的长度
if(left>=right||right>=arraysize)
return ;//返回为空
int mid=(left+right)/2;
for(int i=0;i<mid-left;i++)
{
int temp=A[left+i];
A[left+i]=A[right-i];
A[right-i]=temp;
}
}
void Exchange(int A[],int m,int n,int arraysize)
{
/*数组A[m+n]中,从0到m-1存放顺序表(a1,a2,...am),从m到m+n-1存放顺序表(b1,b2,...bn)算法将这两个表的位置互换 */
Reverse(A,0,m+n-1,arraysize);//整个表逆置
Reverse(A,0,n-1,arraysize);//前n个元素逆置
Reverse(A,n,m+n-1,arraysize);//后m个元素逆置
}
3.带头结点的单链表从尾到头反向输出
方法一:尾插法实现反向输出
方法二:栈来实现
思想:
每经过一个结点,将该结点放入栈中,遍历完整个链表,再从栈顶开始输出结点值
方法三:递归来实现
思想:
每当访问一个结点是,先递归输出它后面的结点,再输出该结点本身,这样链表就反向输出
代码:
void R_print(Linklist L)
{
//从尾到头输出单链表中每个结点的值
if(L->next!=NULL)
{
R_print(L->next);//递归输出后面的结点
}
if(L!=NULL)
print(L->data);//找到最后面的结点就输出对应的data值
}
4.带头结点的单链表就地逆置
方法一:头插法建立单链表
思想:
将头结点摘下,然后从第一结点开始,依次插入到头结点的后面(头插法建立单链表),直到最后一个结点为止,这样就实现了链表的逆置。
代码:
LinkList Reverse_1(LinkList L)
{
LNode*p,*r;//p为工作指针,r为p的后继,以防断链
p=L->next;//从第一个元素结点开始
L->next=NULL;//先将头结点的next域置位NULL
while(P!=NULL)//依次将元素结点摘下
{
r=p->next;//用r暂存p的后继,以防断链
p->next=L->next;//将p结点插入到头结点之后
}
}
方法二.指针反转
思想:
用pre,p,r分别指向三个结点,分别为当前结点的前一个结点,当前结点,当前结点的后一个结点。依次往后面遍历,改变指针的指向,到最后一个结点时,插到头结点的后面
代码:
LinkList Reverse_2(LinkList L)
{
//依次遍历线性表L,并将结点指针反转
LNode*pre,*p=L->next,*r=p->next;//分别用pre,p,r来表示连续的三个结点
p->next=NULL;//处理第一个结点,将第一个结点指针指向NULL。就表示放到链表的尾部
while(r!=NULL)
{
pre=p;//从第二个结点开始依次继续遍历,三个结点往后面移
p=r;
r=r->next;
p->next=pre;//指针反转,第一个反转的是第二个结点指向第一个结点
}
L->next=p;//处理最后一个结点,将最后一个结点放到头结点的后面
return L;
}
5.利用栈和队列实现队列中元素逆置(Q是一个队列,S是一个空栈)
思想:
队列中元素全部出队列再进栈,然后再出栈进队列
代码:
void Inserver(Stack S,Queue Q)
{
while(!QueueEmpty(Q))
{
//若队列不为空
x=Dequeue(Q);//队列中元素全部出队
Push(S,x);//队列中全部元素依次进栈
}
while(StackEmpty(S))
{
//若栈不为空
Pop(S,x);//栈中元素全部出栈
Enqueue(Q);//栈中元素全部入队列
}
}