《数据结构打卡》第8天
0、编写一个算法,要求将奇数最先输出,偶数最后输出(15分)使用栈来操作。
算法思想:
1.假设数组arr[]中的值为{123456},分别用两个栈来输出
2.奇数栈用于存储{1,3,5},偶数栈用于存储{2,4,6}
3.最后用元素e分别从两个栈中取出元素奇数元素在前,偶数元素在后的一个序列,输出为{5,3,1,6,4,2}
void fun(ElemType arr[],int n) //定义数组arr,数组长度为n
{ int i; ElemType e; //i作为计数,e用于将每个元素出栈
SqStack *st1,*st2; //建立两个栈
InitStack(str1);
InitStack(str2);
for (i=0;i<n;i++)
if (arr[i]%2==1) //若第i个值与2的余数为1
Push(str1,arr[i]); //则为奇数,入栈到栈1
else
Push(str2,arr[i]); //若为偶数,入栈到栈2
i=0; //需要将i重新回到0,使得入栈到数组arr[]中的下标是从0开始
while (!StackEmpty(str1))
{
Pop(str1,e); //奇数出栈
arr[i++]=e; //出栈完以后放到数组arr中覆盖原有位置的元素
}
while (!StackEmpty(str2))
{
Pop(str2,e); //偶数出栈
arr[i++]=e; //出栈完以后放到数组arr中覆盖原有位置的元素
}
DestroyStack(str1); //销毁栈1
DestroyStack(str2); //销毁栈2
}
答:算法的执行步骤如下:
(1)扫描数组arr,将所有奇数进到 st1 栈中,将所有偶数进到 st2 栈中。
(2)先将 st1 的所有元素(奇数元素)退栈,并放到数组 a 中并覆盖原有位置的元素;
再将 st2 的所有元素(偶数元素)退栈,并放到数组 a 中并覆盖原有位置的元素。
(3)销毁两个栈 st1 和 st2。
所以本算法的功能是,利用两个栈将数组arr 中所有的奇数元素放到所有偶数元素的前面。
1、设顺序表va中的数据元素递增有序。试设计一个算法,将x插入到顺序表的适当位置上,以保持该表的有序性。(10分)
void Insert_SqList(SqList va,int i,ElemType x){//把x插入递增有序表va中
if(va.length > MAXSIZE) return error;//若表长大于最大容量则错
for(i=va.length-1;va.elem[i]>x&&i>=0;i--){
va.elem[i+1]=va.elem[i];
}
va.elem[i]=x;
va.length++;
}/*Insert_SqList*/
2、试写一算法,实现顺序表的就地逆置,即利用原表的存储空间将线性表(a1, a2,…. an)逆置为(an, an-1,…., a1)。
status Reverse_List(Sqlist L){ //移动线性表,将元素逆序排列
int i; //表示第几个元素
ElmType x; //定义一个临时变量存放元素
for(i=0;i<L.length/2;i++){ //需要移动的元素不超过表长的一半
x = L.elem[i]; //把从第1个开始的值暂存在变量x
L.elem[i] = L.elem[L.length-i-1]; //把从第n个元素开始的值放第1个位置
L.elem[L.length-i-1] = x; //把暂存的第1个值放最后;
}
return ok;
}
//这是另一种顺序表逆置的方法
//推荐使用下面的一种顺序表的逆置算法
Void Reverse(SqList &L){
int i,j; //1.定义两个变量,分别指向表头和表尾
int temp; //2.定义一个临时变量,用于保存待逆置的值
for(i=0,j=L.length-1;i<j;++i,--j){
//i指向表头,j指向表尾,当i下标<j,i向后增1,j向前减1。
temp=L.elem[i]; //3.第一个结点暂存在临时变量中
L.elem[i]=L.elem[j]; //4.最后一个结点放第一个位置
L.elem[j]=temp; //取出第1个结点放最后一个位置
}
}
3、编写算法,实现带头结点单链表的逆置算法(10分)
算法思路:首先把头结拆下来,然后使用头插法的方式依次把每个结点倒序接入到头结点之后。
void Reverse_L(Linklist &L){ //采用头插法逆置带头结点
Lnode *p,*r; p = L->next; //p指向首元结点
if(!p->next || !p->next->next) return; //若为空表或表长为1时不做处理 如果没要求判断是否为空表或表长为1时则可以不用写这段。
L->next = Null; //拆开头结点,指针域设为空
while(p!=Null){
r = p->next; //r暂存p的后继结点
p->next = L->next; //采用头插法,将p结点插入到头结点之后
L->next = p; //头结点始终指向新插入的结点
p = r; //结点插入完以后,p指向下一结点
}
}
3、已知指针 Ta和 Tb分别指向两个单循环链表的尾结点,设计一个算法将这两个链表连接在一起**(5分)**
①先用p指针保存Ta的头结点
②Ta的next域链接Tb的首元结点
③释放掉Tb的头结点
④Tb的next指向Ta的表头结点
Stutus Connect_L(LinkList &Ta,LinkList &Tb){
LinkList *p = Ta->next;//先用p指针保存Ta的头结点
Ta->next = Tb->next->next; //再Ta的next域链接Tb的首元结点
delete Tb->next; //释放掉Tb的头结点
Tb->next = p;//修改Tb的next指向Ta的表头结点
//构成单向循环链表
}
4、编写一个算法,计算带头结点单链表head中所有值为X的结点的个数
int Length_List(Linklist head,ElemType X){
int i = 0;
LNode *p = head->next; //p指向首元结点
while(p){//p若不为空则指向下一结点
if(p->data == X) //若p的数据域的值等于值X
i++; //计数器首先+1
p = p->next; //然后p继续指向下一结点
}
return i; //最后返回值x的结点个数
//这一步相当于求单链表的表长一样,只不过加了if条件判断值是否为x。
}
5、设计一个算法,在给定值x之后插入新结点