《数据结构打卡》第8天(自定义算法篇)

《数据结构打卡》第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之后插入新结点

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值