[作业]【C语言实现】假设两个按元素值递增有序排列的线性表A和B,均以单链表作为存储结构,请编写算法,将A表和B表归并成一个按元素值递减有序排列的线性表C,并要求利用原表结点。

习题一:

  1. 问题描述
    假设两个按元素值递增有序排列的线性表A和B,均以单链表作为存储结构,请编写算法,将A表和B表归并成一个按元素值递减有序排列的线性表C,并要求利用原表(即A表和B表的)结点空间存放表C。
  2. 输入格式
    输入的第一行表示测试数据的组数T
    后面跟着T组输入
    每组测试数据占三行
  3. 输出格式
    返回链表A和B按照上述要求处理后形成的链表C的遍历结果,链表C按元素值递减有序排列,长度为lenC(lenC = lenA + lenB)。输出时链表C每个元素之间用空格进行分割,并且最后要换行!
  4. 备注
    1、使用原表A和B的节点空间存放C。
    2、写清楚注释,让审核人能理解你的思路(代码通过并且有详细的注释这题才会给满分)。
    3、必须按照题目要求进行排序,不得通过数组排序来获取结果!
    下面展示一些 。

输入样例

2
5 5
1 2 3 4 5
1 2 3 4 5
3 3
2 4 8
3 6 9

输出样例

5 5 4 4 3 3 2 2 1 1
9 8 6 4 3 2

代码实例。

#include <stdio.h>
#include <stdlib.h>
#define MAXINT 100

typedef struct Node {
	int data ;
    struct Node* next ;
}Node;

typedef struct Node* LinkList ;

//打印一个单链表
void ShowList(LinkList l) {
	
	LinkList p ;
	p = (LinkList)malloc(sizeof(Node));
	p = l->next ;
	while(p != NULL){
		printf("%d ", p->data) ;
		p = p->next ;
	}
} 

//创建一个单链表
LinkList CreatLinkList(int n) {
	
	Node *h, *p, *q ; //设置三个结点,h保存la的头节点,q一直指向la的尾结点,p存储输入数据;
	h = (LinkList)malloc(sizeof(Node));
    h->next = NULL ; //初始化链表 ,让它成为一个空表 
	q = h ;  //开始时la的头结点与尾结点重合 
	
	int  i ;
	
	for (i = 0; i < n; i ++) {	
		p = (LinkList)malloc(sizeof(Node)) ;
		scanf("%d", &p->data) ;
		p->next = q->next ;
		q->next = p ; 
		q = p ;
	} 
	
	return h ;
} 

//倒置链表中的数据

LinkList ReverseList(LinkList l) {
	
	Node *p, *q ; //设置两个结点 
	p = l->next ; //p是l的第一个数据结点
	l->next = NULL ; //将l移位指向链表末尾的结点,我们在l的后面重新将原本的数据插入,构成一个新的逆置链表
	
	while(p){
		q = p->next ; //将p的下一位结点保存在q中
		p->next = l->next ;
		l->next = p ; //将p插入在L之后
		p = q ;//完成p的后移 
	} 
	
	return l ; 
} 

//按照递增顺序并置两个链表,最后转置数据 
LinkList MergeList(LinkList la, LinkList lb) {
	LinkList pa, pb;
    pa = la->next; //pa和pb分别指向la和lb的第一个数据结点 
    pb = lb->next;
    LinkList pc = la;//以La的头结点为并置的头结点 
    
    while(pa && pb){
        if(pa->data <= pb->data)//pa里数据比pb小,就连接pa指向的结点,pa指向la的后一个
        {
            LinkList qa = pa->next; //存储pa下一个结点的数据 
            pa->next = NULL; //将pa指针直接指向la的末尾,相当于将pa->data这个元素从队列中分离出来 
            pc->next = pa; //pc是一个准备摘取数据的指针,当pa小时,pc就指向pa,将已经摘取出的元素放在自己的链表里 
            pc = pc->next;
            pa = qa; //pa指针后移一个位置 
        }
        else{//pb里数据较小,就连接pb指向的结点,pb指向lb的后一个,同理 
            LinkList qb = pb->next;
            pb->next = NULL;
            pc->next = pb;
            pc = pc->next;
            pb = qb;
        }
    }
    pc->next = pa ? pa : pb;//合并剩下的没遍历完的部分
    return la;
} 

LinkList ProjectEntrance() {
	
	int n1, n2 ;
	scanf("%d %d", &n1, &n2) ;
	LinkList la ;
	LinkList lb ;
	la = CreatLinkList(n1) ; //创建链表并输入数据 
	lb = CreatLinkList(n2) ;	
	LinkList lc ;
	lc =  MergeList(la, lb) ; //按照原有顺序并置两个列表 
	return lc ;	
	
}

int main() {
	
	LinkList l[MAXINT] ;
	int i, j, n ;
	scanf("%d", &n) ;
	for( i = 0 ; i < n ; i ++ ){ 
	l[i] = 	ProjectEntrance() ;
	ReverseList(l[i]) ;  //逆置链表得到题目要求顺序 
	} 		
	for( i = 0;i < n ; i ++) {
		ShowList(l[i]) ;
		for(j = 0; j < n - 1 ; j ++ ){
		printf("\n") ;
		}
	}

	return 0 ;
}

习题二:

  1. 问题描述
    设线性表A=(a1, a2,…,am),B=(b1, b2,…,bn),试写一个按下列规则合并A、B为线性表C的算法,使得:
    C= (a1, b1,…,am, bm, bm+1, …,bn) 当m≤n时;
    C= (a1, b1,…,an, bn, an+1, …,am) 当m>n时。
    线性表A、B、C均以单链表作为存储结构,且C表利用A表和B表中的结点空间构成。
  2. 输入格式
    输入的第一行表示测试数据的组数T
    后面跟着T组输入
    每组测试数据占三行。

测试数据的第一行有两个正整数,分别为链表A和B的长度lenA,lenB(1 <= lenA, lenB <= 1000)。链表内的元素为ai,bj (-10000<= ai, bj <=10000)。

测试数据的后两行分别是链表A和B。
3. 输出格式
返回链表A和B按照上述要求处理后形成的链表C的遍历结果,,链表C长度为lenC(lenC = lenA + lenB)。输出时链表C每个元素之间用空格进行分割,并且最后要换行!
3. 备注
1、使用原表A和B的节点空间存放C。
2、写清楚注释,让审核人能理解你的思路(代码通过并且有详细的注释这题才会给满分)。
3、必须按照题目要求使用链表进行处理,不得使用数组来获取数据与获取结果!

输入样例

2
3 4
1 2 3
1 2 3 4
5 2
1 1 1 1 1
2 2

输出样例

1 1 2 2 3 3 4
1 2 1 2 1 1 1

代码实例。

#include <stdio.h>
#include <stdlib.h>
#define MAXINT 100

typedef struct Node {
	int data ;
    struct Node* next ;
}Node;

typedef struct Node* LinkList ;

//打印一个单链表
void ShowList(LinkList l) {
	
	LinkList p ;
	p = (LinkList)malloc(sizeof(Node));
	p = l->next ;
	while(p != NULL){
		printf("%d ", p->data) ;
		p = p->next ;
	}
} 

//创建一个单链表
LinkList CreatLinkList(int n) {
	
	Node *h, *p, *q ; //设置三个结点,h保存la的头节点,q一直指向la的尾结点,p存储输入数据;
	h = (LinkList)malloc(sizeof(Node));
    h->next = NULL ; //初始化链表 ,让它成为一个空表 
	q = h ;  //开始时la的头结点与尾结点重合 
	
	int  i ;
	
	for (i = 0; i < n; i ++) {	
		p = (LinkList)malloc(sizeof(Node)) ;
		scanf("%d", &p->data) ;
		p->next = q->next ;
		q->next = p ; 
		q = p ;
	} 
	
	return h ;
} 


//按照要求顺序并置两个链表
LinkList MergeList(LinkList la, LinkList lb) {
	LinkList pa, pb, qa, qb;
    pa = la->next; //pa和pb分别指向la和lb的第一个数据结点 
    pb = lb->next;
    LinkList pc = la;//以La的头结点为并置的头结点 
    
    while(pa && pb){
    	    
    	    //完成pc指向la存储的元素过程 
    	    qa = pa->next; //存储pa下一个结点的数据 
		    pa->next = NULL; //将pa指针直接指向la的末尾,相当于将pa->data这个元素从队列中分离出来 
            pc->next = pa; //pc是一个准备摘取数据的指针,将已经摘取出的元素放在自己的链表里 
            pc = pc->next;
            pa = qa; //pa指针后移一个位置 
            
            //完成 pc指向lb存储的元素过程
            qb = pb->next ;
            pb->next = NULL;
            pc->next = pb ;
            pc = pc->next ;
            pb = qb ; 
    }
           pc->next = pa ? pa : pb;//最后进行判断,合并剩下的没遍历完的部分
    
	return la;
} 

LinkList ProjectEntrance() {
	
	int n1, n2 ;
	scanf("%d %d", &n1, &n2) ;
	LinkList la ;
	LinkList lb ;
	la = CreatLinkList(n1) ; //创建链表并输入数据 
	lb = CreatLinkList(n2) ;	
	LinkList lc ;
	lc =  MergeList(la, lb) ; //按照原有顺序并置两个列表 
	return lc ;	
	
}

int main() {
	
	LinkList l[MAXINT] ;
	int i, j, n ;
	scanf("%d", &n) ;
	for( i = 0 ; i < n ; i ++ ){ 
	l[i] = 	ProjectEntrance() ;
	} 		
	for( i = 0;i < n ; i ++) {
		ShowList(l[i]) ;
		for(j = 0; j < n - 1 ; j ++ ){
		printf("\n") ;
		}
	}

	return 0 ;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值