数据结构-第二章线性表-算法设计题5

算法设计题

问题描述

        5.设计算法将一个带头结点的单链表A分解为两个具有相同结构的单链表B和C,其中B表的结点为A表中值小于零的结点,而C表的结点为A表中值大于0的结点(链表A中的元素为非零整数,要求B、C表利用A表的结点)。

算法分析

      此题的关键点在于:

                1.LB表的头结点可以使用原来LA表的头结点,而需要为LC表新申请一个头结点。

                2.对LA表进行遍历的同时进行分解,完成结点的重新链接,在此过程中需要记录遍历的后继结点以防止链接后丢失后继结点。

                3.本题并未要求链表中结点的数据值有序,所以在摘取满足条件的结点进行链接时,可以采用前插法,也可以采取后插法。因为前插法的实现相对简单,下面的算法描述中采取了前插法。

算法步骤

        1.首先将LB表的头结点初始化LA表的头结点,为LC表新申请一个头结点,初始化为空表。
        2.从LA表的首元结点开始,依次对LA表进行遍历。p为工作指针,q为p的后继指针。 
        3.当p->data<0时,将p指向的结点使用前插法插入到LB表。 
        4.当p->data>0时,将p指向的结点使用前插法插入到LC表,然后p指向新的待处理的结点(p=q)。 

算法描述

        主要代码

void Decompose(LinkList &LA,LinkList &LB,LinkList &LC)
{
	//单链表LA分解为两个具有相同结构的链表LB和LC 
	LinkList pa=LA->next;
	LinkList pb=LA;			
	pb->next=NULL;			//LB表初始化
	LinkList pc=LC=new LNode;	//为LC申请结点空间
	pc->next=NULL;			//LC初始化为空表
	LinkList p=pa;	//p为工作指针
	while(p!=NULL)
	{
		LinkList q=p->next;	//暂存p的后继
		if(p->data<0)		//将小于0的结点链入LB表,前插法 
		{
			p->next=pb->next;
			pb->next=p;	
		} 
		else				//将大于0的结点链入LC表,前插法 
		{
			p->next=pc->next;
			pc->next=p;
		}
		p=q;				//p指向新的待处理结点 
	} 		
 } 

        完整代码

//******************************数据结构-第二章线性表-算法设计题5******************************// 
#include <stdio.h>
#include <iostream>
#define OK 1
#define ERROR 0
using namespace std;
typedef int Status;
//定义单链表的结构类型
typedef int ElemType;
//------单链表的存储结构-----// 
typedef struct LNode
{
	ElemType data;	     //结点的数据域
	struct LNode *next;	//结点的指针域,指向下一个指针 
 }LNode,*LinkList;      // LNode是结点,LinkList是链表,LinkList为指向结构体LNode的指针类型 

//------单链表的初始化-----//
  //【算法步骤】//
	//1.生成新结点作为头结点,用头指针L指向头结点。
	//2.头结点的指针域置空。
Status InitList(LinkList &L)
{
	//构造一个空的单链表L
	L=new LNode;      //生成新结点作为头结点,用头指针L指向头结点  或L=(LinkList)malloc(sizeof(LNode))
	L->next=NULL;     //头结点的指针域置空
	return OK; 
 } 
 
//------后插法创建单链表-----//
  //【算法步骤】//
	//1.创建一个只有头结点的空链表。
	//2.尾指针r初始化,指向头结点。 
	//3.根据创建链表包括的元素个数n,循环n次执行以下操作:
	   //生成一个新结点*P; 
	   //输入元素值赋给新结点*p的数据域;
	   //将新结点*p插入到尾结点*r之后;
	   //尾指针r指向新的尾结点*p。 
void CreateList_R(LinkList &L,int n)
{
	//正位序输入n个元素的值,建立带表头结点的单链表L
	L=new LNode;      //或L=(LinkList)malloc(sizeof(LNode))
	L->next=NULL;    //先建立一个带头结点的空链表 	
	LinkList r=L;             //尾指针r指向头结点 
	for(int i=0;i<n;++i)
	{
		LinkList p=new LNode;  //生成新结点*p
		cin>>p->data;  //输入元素值赋给新结点*p的数据域
		p->next=NULL;
		r->next=p;    //将新结点*p插入到尾结点*r之后 
		r=p;          //r指向新的尾结点*p 
	 }
 }

//------单链表的插入-----//
  //【算法步骤】//
  //将值为e的新结点插入到表的第i个结点的位置上,即插入到结点ai-1与ai之间,具体插入过程如图所示,步骤如下: 
	//1.查找结点ai-1并由指针p指向该结点。
	//2.生成一个新结点*s。 
	//3.将新结点*s的数据域置为e。 
	//4.将新结点*s的指针域指向结点ai。
	//5.将结点*p的指针域指向新结点*s。
Status ListInsert(LinkList &L,int i,ElemType e)
{
	//在带头结点的单链表L中第i个位置插入值为e的新结点 
	LinkList p=L;
	int j=0;
	while(p && (j<i-1)) 
	{
		p=p->next;   //查找第i-1个结点,p指向该结点 
		++j;
	}
	if(!p||j>i-1) return ERROR;  //i>n+1或者i<1
	LinkList s=new LNode;    //生成新结点*s 
	s->data=e;		//将结点*s的数据域置为e 
	s->next=p->next;//将结点*s的指针域指向结点ai 
	p->next=s;		//将结点*p的指针域指向结点*s 
	return OK; 	 
 }
 
//------链表的分解-----//
  //【算法步骤】//
	//1.首先将LB表的头结点初始化LA表的头结点,为LC表新申请一个头结点,初始化为空表。
	//2.从LA表的首元结点开始,依次对LA表进行遍历。p为工作指针,q为p的后继指针。 
	//3.当p->data<0时,将p指向的结点使用前插法插入到LB表。 
	//4.当p->data>0时,将p指向的结点使用前插法插入到LC表,然后p指向新的待处理的结点(p=q)。 
void Decompose(LinkList &LA,LinkList &LB,LinkList &LC)
{
	//单链表LA分解为两个具有相同结构的链表LB和LC 
	LinkList pa=LA->next;
	LinkList pb=LA;			
	pb->next=NULL;			//LB表初始化
	LinkList pc=LC=new LNode;	//为LC申请结点空间
	pc->next=NULL;			//LC初始化为空表
	LinkList p=pa;	//p为工作指针
	while(p!=NULL)
	{
		LinkList q=p->next;	//暂存p的后继
		if(p->data<0)		//将小于0的结点链入LB表,前插法 
		{
			p->next=pb->next;
			pb->next=p;	
		} 
		else				//将大于0的结点链入LC表,前插法 
		{
			p->next=pc->next;
			pc->next=p;
		}
		p=q;				//p指向新的待处理结点 
	} 		
 } 

//------打印单链表函数-----//  
void PrintList(LinkList L)
{
	printf("当前单链表中所有元素为:");
	for(LinkList p=L->next;p!=NULL;p=p->next)
	{
		if(p->next==NULL)
			printf("%d",p->data);
		else
			printf("%d->",p->data);
	}
	printf("\n"); 
}

//------创建单链表函数------//
void CreateList_LA(LinkList &L) 
{
	int n;
	printf("请输入要创建的单链表LA的长度:");
	scanf("%d",&n);
	printf("请依次输入%d个数(空格隔开):",n);
	CreateList_R(L,n);
	printf("单链表LA创建成功!\n");
	PrintList(L);
}
void CreateList_LB(LinkList &L) 
{
	int n;
	printf("请输入要创建的单链表LB的长度:");
	scanf("%d",&n);
	printf("请依次输入%d个数(空格隔开):",n);
	CreateList_R(L,n);
	printf("单链表LB创建成功!\n");
	PrintList(L);
}
void CreateList_LC(LinkList &L) 
{
	int n;
	printf("请输入要创建的单链表LC的长度:");
	scanf("%d",&n);
	printf("请依次输入%d个数(空格隔开):",n);
	CreateList_R(L,n);
	printf("单链表LC创建成功!\n");
	PrintList(L);
}

//------单链表插入函数------//
void InsertList(LinkList &L)
{
	int i,e;
	printf("请输入要插入的位置:");
	scanf("%d",&i);
	printf("请输入要在第%d个位置插入的数据元素:",i);
	scanf("%d",&e); 
	bool flag=ListInsert(L,i,e);
	if(flag)
	{
		printf("元素%d插入单链表成功!\n", e);
		PrintList(L);	
	}
	else
	{
		printf("元素%d插入单链表失败!\n",e);
	}	
 } 
 
//------单链表合并函数------//
void DecomposeList(LinkList LA,LinkList LB,LinkList LC)
{
	Decompose(LA,LB,LC);
	printf("LA分解为LB的数据元素:\n");
	PrintList(LA);
	printf("LA分解为LC的数据元素:\n");
	PrintList(LC);
}

//------主函数-----//
int main()
{	
	int n;
	LinkList LA,LB,LC; 
	InitList(LA);
	InitList(LB);
	InitList(LC);
	CreateList_LA(LA);
	DecomposeList(LA,LB,LC);
 } 

        运行结果

请输入要创建的单链表LA的长度:5
请依次输入5个数(空格隔开):5 -3 2 -1 4
单链表LA创建成功!
当前单链表中所有元素为:5->-3->2->-1->4
LA分解为LB的数据元素:
当前单链表中所有元素为:-1->-3
LA分解为LC的数据元素:
当前单链表中所有元素为:4->2->5

--------------------------------
Process exited after 15.67 seconds with return value 0
请按任意键继续. . .

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值