沈师PTA数据结构第2章实验题集2—链表操作

R7-1 两个有序链表序列的合并 (20 分)

已知两个非降序链表序列S1与S2,设计函数构造出S1与S2合并后的新的非降序链表S3。

输入格式:

输入分两行,分别在每行给出由若干个正整数构成的非降序序列,用−1表示序列的结尾(−1不属于这个序列)。数字用空格间隔。

输出格式:

在一行中输出合并后新的非降序链表,数字间用空格分开,结尾不能有多余空格;若新链表为空,输出NULL

输入样例:

1 3 5 -1
2 4 6 8 10 -1
结尾无空行

输出样例:

1 2 3 4 5 6 8 10
结尾无空行
#include<iostream>
using namespace std;
#define MAX 9999999

int s1[MAX],s2[MAX],s3[MAX];
int main() {
	int x;
	int i=0,j=0,k=0;
	while(cin>>x&&x>0) {
		s1[i++]=x;
	}
	while(cin>>x&&x>0) {
		s2[j++]=x;
	}

	if(i==0&&j==0) {
		cout<<"NULL"<<endl;
		return 0;
	}

	int p=0,s=0;
	while(i&&j) {
		if(s1[p]<s2[s]) {
			s3[k++]=s1[p++];
			i--;
		} else {
			s3[k++]=s2[s++];
			j--;
		}
	}

	while(i) {
		s3[k++]=s1[p++];
		i--;
	}
	while(j) {
		s3[k++]=s2[s++];
		j--;
	}

		int cnt=0;
		for(int i=0; i<k; i++) {
			if(cnt++)
				cout<<" ";
			cout<<s3[i];
		}
    cout<<"\n";
	return 0;
}

R7-2 两个有序链表序列的交集 (20 分)

已知两个非降序链表序列S1与S2,设计函数构造出S1与S2的交集新链表S3。

输入格式:

输入分两行,分别在每行给出由若干个正整数构成的非降序序列,用−1表示序列的结尾(−1不属于这个序列)。数字用空格间隔。

输出格式:

在一行中输出两个输入序列的交集序列,数字间用空格分开,结尾不能有多余空格;若新链表为空,输出NULL

输入样例:

1 2 5 -1
2 4 5 8 10 -1
结尾无空行

输出样例:

2 5
结尾无空行
#include "stdio.h"
#include "math.h"
#define N 100000

typedef struct linknode{
    int data;
    struct linknode *next;
}node,*ptr;
 
int main(){
    ptr s1,s2,s3,p,q,z,last;
    int x;
    s1 = NULL;
    s2=NULL;
    s3=NULL;

    //后向插入方法
    scanf("%d",&x);
    while(x>=0){
        p=(ptr)malloc(sizeof(node));
        p->data=x;
        if (s1==NULL) {
            p->next=s1;s1=p;last=p;
        }else{
            last->next=p;p->next=NULL;last=p;
        }
        scanf("%d",&x);//read next
    }
    
    scanf("%d",&x);
    while (x>=0) {
        p=(ptr)malloc(sizeof(node));
        p->data=x;
        if (s2==NULL) {
            p->next=s2;s2=p;last=p;
        }else{
            last->next=p;p->next=NULL;last=p;
        }
        scanf("%d",&x);
    }
    s3=(ptr)malloc(sizeof(node));
    s3->next=NULL;
    for (p=s1,q=s2,z=s3; p!=NULL && q!=NULL; ) {
        if (p->data==q->data) {
            z->next=p;
            z=z->next;
            //printf("%d",p->data);
            p=p->next;
            q=q->next;
        }else if (p->data<q->data){
            p=p->next;
        }else if (p->data>q->data){
            q=q->next;
        }
    }
     
    if ((s3->next==NULL||s1==NULL)||s2==NULL) {
        printf("NULL");
    }else{
        p = s3->next;
        while (p!=NULL) {
            printf("%d",p->data);
            if (p->next!=NULL) {
                printf(" ");
            }
            p=p->next;
        }
    }
}
 

单链表的创建及遍历 (20 分)

读入n值及n个整数,建立单链表并遍历输出。

输入格式:

读入n及n个整数。

输出格式:

输出n个整数,以空格分隔(最后一个数的后面没有空格)。

输入样例:

在这里给出一组输入。例如:

2
10 5
结尾无空行

输出样例:

在这里给出相应的输出。例如:

10 5
结尾无空行
#include<stdio.h>
#include<stdlib.h>
typedef struct node{
    int data;
    struct node*next;
}linklist;//定义结构体链表

linklist *CreatListR(int n){
    int i,m;
    linklist  *head,*s,*r;    
    head=(linklist*)malloc(sizeof(linklist));    
    r=head;    
    for(i=0;i<n;i++){                
    s=(linklist*)malloc(sizeof(linklist));        
    scanf("%d",&m);       
     s->data=m;       
      r->next=s;        
      r=s;                   
    }
      r->next=NULL;    
      return head;}

      int main(){    
          int n;
          scanf("%d",&n);
          if(n<=0) return 0;
          linklist *s;
          s=CreatListR(n);
          s=s->next;
          printf("%d",s->data);
          while(s->next!=NULL){
            s=s->next;
            printf(" %d",s->data);
          }
          printf("\n");
      return 0;
}

R7-4 求链式线性表的倒数第K项 (20 分)

给定一系列正整数,请设计一个尽可能高效的算法,查找倒数第K个位置上的数字。

输入格式:

输入首先给出一个正整数K,随后是若干非负整数,最后以一个负整数表示结尾(该负数不算在序列内,不要处理)。

输出格式:

输出倒数第K个位置上的数据。如果这个位置不存在,输出错误信息NULL

输入样例:

4 1 2 3 4 5 6 7 8 9 0 -1
结尾无空行

输出样例:

7
结尾无空行
#include<iostream>
#include<stack>
using namespace std;
int main(){
	stack<int> q;
	int flag=1,k,count=0;
	cin>>k;
	while(flag){
		int t;
		cin>>t;
		if(t<0)
		flag=0;
		else{
			q.push(t);
			count++;
		}
	}
	if(k>count)
	cout<<"NULL";
	else{
		for(int i=1;i<k;i++)
		q.pop();
		cout<<q.top();
	}
	cout<<"\n";
}

R7-5 链表倒数n个结点的乘积 (20 分)

本题要求计算单链表倒数n个结点的乘积。例如,给出单链表1 2 3 4 5,则倒数2个结点的乘积为20。

输入格式:

输入有2行,第一个行为2个非负整数m和n。其中m为链表结点个数,n为链表倒数结点的数量。题目保证计算结果在int范围内。 第二行为链表的m个数,以空格分隔。

输出格式:

在一行中输出倒数n个结点的乘积。

输入样例:

5 2
1 2 3 4 5
结尾无空行

输出样例:

20
结尾无空行

样例解释:

20 = 4 * 5

#include<stdio.h>
#include<malloc.h>
 
typedef struct node{
	int data;
	struct node *next;
}LinkListNode;

LinkListNode* CreateList(int a[],int m){
	LinkListNode *node,*head,*p;
	int i;
	head = (LinkListNode*)malloc(sizeof(LinkListNode));
	p = head;
	
    for(i = 0;i<m;i++){
		node = (LinkListNode*)malloc(sizeof(LinkListNode));
		node->data = a[i];
		p->next = node;
		p = node;
	}
	p->next = NULL;
	return head;
} 

int main(){
	int m,n;//m为链表结点个数,n为链表倒数结点的数量
	int i;
	scanf("%d %d",&m,&n);
	int a[m];
	for(i = 0;i<m;i++){
		scanf("%d",&a[i]);
	}
    
	LinkListNode *head,*p;
	head = CreateList(a,m);
	p = head->next;
	int local = m-n;
	if(local == m){
		printf("0");
		return 0;
	}
	for(i = 0;i < local;i++){
		p = p->next;
	}
 
	int result = 1;
	for(i = 0;i<n;i++){
		result = result * p->data;
		if(p->next == NULL){
			break;
		}
		p = p->next;
	}
	printf("%d\n",result);
	return 0;
}

R7-6 在有序链表中插入数据 (20 分)

给定一批严格递增排列的整型数据,给定一个x,若x不存在,则插入x,要求插入后保持有序。存在则无需任何操作。

输入格式:

输入有两行: 第一个数是n值,表示链表中有n个数据。后面有n个数,分别代表n个数据。 第二行是要插入的数。

输出格式:

输出插入后的链表数据,以空格分开。行末不能有多余的空格。

输入样例1:

在这里给出一组输入。例如:

5 1 3 6 9 11
4
结尾无空行

输出样例1:

在这里给出相应的输出。例如:

1 3 4 6 9 11
结尾无空行

输入样例2:

在这里给出一组输入。例如:

5 1 3 6 9 11
3
结尾无空行

输出样例2:

在这里给出相应的输出。例如:

1 3 6 9 11
结尾无空行
#include<bits/stdc++.h>
using namespace std;

template <typename DataType>
struct Node{
    DataType data;               //数据域
    Node<DataType> *next;       //指针域
};

template <typename DataType>
class LinkList{
public:
    LinkList();                      //无参构造函数,建立只有头结点的空链表
    LinkList(DataType a[], int n);       //有参构造函数,建立有n个元素的单链表
    ~LinkList();                     //析构函数
    int Length();                     //求单链表的长度
    void Insert(DataType x);       //插入操作,第i个位置插入值为x的结点
    void PrintList( );                  //遍历操作,按序号依次输出各元素
private:
    Node<DataType> *first;           //单链表的头指针
};

template <typename DataType>
LinkList<DataType> :: LinkList( ){
    first = new Node<DataType>;              //生成头结点
    first->next = nullptr;                      //头结点的指针域置空
}

template <class DataType>
LinkList<DataType> :: ~LinkList( ){
    Node<DataType> *q = NULL;
    while (first != NULL){        //释放单链表的每一个结点的存储空间
        q = first;                 //暂存被释放结点
        first = first->next;         // first指向被释放结点的下一个结点
        delete q;
    }
}
template <typename DataType>
void LinkList<DataType> :: PrintList( ){
    int flag=0;
    Node<DataType> *p = first->next;                //工作指针p初始化
    while (p!= nullptr){
        if(flag==0){
            cout << p->data;
            flag=1;
        }else{
            cout << " "<< p->data ;
        }
        p = p->next;                 //工作指针p后移,注意不能写作p++
    }
    cout<<endl;

}

/*插入函数*/
template <typename DataType>
void LinkList<DataType> :: Insert(DataType x){
    Node<DataType> *Z = new Node<DataType>;
    Z->data = x;
    Node<DataType> *p = first, *s = first->next;
    //工作指针p指向要插入的前一个结点
    //s为p之后的一个结点,判断是否与要插入的值相等
    
    if (p->next == NULL)//链表为空链表
    {//要插入的元素放在开头
        Z->next = NULL;
        p->next = Z;
        p = Z;
        return;
    }
    
    while (s->data <Z->data&&s->next!=nullptr){//查找第i – 1个结点
        p = p->next;
        s=s->next;
    }

    if(s->data == Z->data){//元素已存在
        delete Z;//删除要插入的结点
        return;
    }    
    if(s->data>Z->data){
    Z->next = p->next; //将结点Z插入到结点p之后
    p->next = Z;
    return;
    }
    if(s->next==nullptr){//找到链表结尾了,也找不到第i-1个结点
        s->next=Z;//将结点插在最后
        Z->next=nullptr;
        return;
    }
}

template <typename DataType>
LinkList<DataType> :: LinkList(DataType a[ ], int n){
    first = new Node<DataType>;                    //生成头结点
    Node<DataType> *r = first, *s = nullptr;           //尾指针初始化
    for (int i = 0; i < n; i++){
        s = new Node<DataType>;
        s->data = a[i];
        r->next = s;
        r = s;                 //将结点s插入到终端结点之后
    }
    r->next = nullptr;        //单链表建立完毕,将终端结点的指针域置空
}


int main( ){
    int a[10000];
    int i,n;
    cin>>n;
    for(i=0;i<n;i++){
        cin>>a[i];
    }
    LinkList<int> L(a,n);
    int b;
    cin>>b;
    L.Insert(b);
    L.PrintList();
    return 0;
}

posted @ 2021-10-15 12:44  Xinfei_Eva™  阅读(611)  评论(0编辑  收藏  举报