沈师PTA数据结构2021编程复习题

R7-1 二分查找 (15 分)

输入n值(1<=n<=1000)、n个非降序排列的整数以及要查找的数x,使用二分查找算法查找x,输出x所在的下标(0~n-1)及比较次数。若x不存在,输出-1和比较次数。

输入格式:

输入共三行: 第一行是n值; 第二行是n个整数; 第三行是x值。

输出格式:

输出x所在的下标(0~n-1)及比较次数。若x不存在,输出-1和比较次数。

输入样例:

4
1 2 3 4
1
结尾无空行

输出样例:

0
2
结尾无空行
/*按照书上正常折半查找的思想编写*/
#include<iostream>
using namespace std;
extern int sum=0;

int BinarySearch(int a[],const int &x,int n){  //const相当于Java中的final
    int left = 0;
    int right = n-1;
    while (left <= right){
        sum++;
        int middle = (left + right)/2;
        if(x == a[middle]) return middle;  //如果要查的x值等于a[middle],则返回middle
        if(x > a[middle]) left = middle + 1; //如果要查的x值大于a[middle],左侧端点值=中间值middle+1
        else right = middle - 1;   //否则右侧端点值=中间值middle-1
    }
    return -1;
}
int main(){
    int n,a[1000],x,result;
    cin>>n;   //输入第一行n值
    for(int i=0;i<n;i++)
        cin>>a[i];  //输入n个元素
    cin>>x;  //输入要查的x值

    result = BinarySearch(a,x,n);
    cout<<result<<endl<<sum;
    return 0;
}
/*之前做作业的时候在网上找的,不是很理解为什么,但是在Clion和Visual Studio2019编辑器中按照题中给的测试用例输出结果是0 1,但在PTA中提交 亦能通过*/
#include<iostream>
using namespace std;
int num[1005];
int main(){
	int n;
	cin>>n;
	for(int i=0;i<n;i++){
		cin>>num[i];
	}
	int x;
	cin>>x;
	int l=0;
	int h=n-1;
	int count=0;
	int t=(l+h)/2;
	while(l!=h){
		count++;
		t=(l+h)/2;
		if(num[t]==x){
			cout<<t<<endl<<count+1<<endl;
			return 0;
		}
		if(num[t]>x){
			h=t;
		}else if(num[t]<x){
			l=t;
		}
		if(l==(h-1)){
			break;
		}
	}
	if(num[h]==x){
			cout<<h<<endl<<count<<endl;
	}else if(num[l]==x){
			cout<<l<<endl<<count<<endl;
	}else{
		cout<<-1<<endl<<count<<endl;
	}
	return 0;
}

R7-2 二分查找 (20 分)

利用二分查找找出所给出的数在数组中的下标

输入格式:

第一行输入n和m表示数组有n个数据,m表示要对m个数进行查找

输出格式:

所有输出在一行完成,行末没有多余空格和多余回车。

输入样例:

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

输出样例:

0 1 2 3 4
结尾无空行
#include <iostream>
using namespace std;
int BinarySearch(const int a[],int n,int x)
{
    int low,high,mid;
    low=0;
    high=n;
    while(low<=high){
        mid=(low+high)/2;
        if(x<a[mid])
            high=mid-1;
        else if(x>a[mid])
            low=mid+1;
        else
            return mid;
    }
    return 0;
}
int main(){
    int n,m;
    int a[100000],b[100000];
    int i,j;
    cin >> n >> m;
    for(i=0;i<n;i++){
        cin >> a[i];
    }
    for(j=0;j<m;j++){
        cin >> b[j];
        for(i=0;i<n;i++){
            if(j==0)
            {cout << BinarySearch(a,n,b[0]);break;}
            else
            {cout << " " << BinarySearch(a,n,b[j]);break;}
        }
    }
    return 0;
}

R7-3顺序表的建立及遍历

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

输入格式:

读入n及n个整数

输出格式:

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

输入样例:

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

4
-3 10 20 78
结尾无空行

输出样例:

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

-3 10 20 78
结尾无空行
代码
#include "iostream"
using namespace std;
int main(){
    int n; //输入元素个数
    cin >> n;
    int arr[n]; //将元素放在数组中
    for (int i = 0; i < n; i++) {
        cin >> arr[i];  //输入数组元素
    }
    /*方法一:*/
    for (int j = 0; j < n; j++) {
        if (j==0){  //当输出第一个元素时,元素前面无空格
            cout << arr[j];
        } else{     //其余元素前面有空格
            cout << " " <<arr[j];
        }
    }
    /*方法二:*/
    /*for (int j = 0; j < n; j++) {
        if (j!=n-1){  //当输出不是最后一个元素时,输出元素后加一个空格
            cout << arr[j] << " ";
        } else{     //最后一个元素,不输出元素后的空格。
            cout << arr[j];
        }
    }*/
}
#include <stdio.h>
int main(){
    int a;
    scanf("%d",&a);
    int arr[a];
    for(int i=0;i<a;i++){
        scanf("%d",&arr[i]);
    }
     for(int i=0;i<a;i++){
         if(i!=a-1){
             printf("%d ",arr[i]);
         }else{
             printf("%d",arr[i]);
         }
    }
    printf("\n");
    return 0;
}

R7-4 jmu-ds-顺序表区间元素删除 (20 分)

若一个线性表L采用顺序存储结构存储,其中所有的元素为整数。设计一个算法,删除元素值在[x,y]之间的所有元素,要求算法的时间复杂度为O(n),空间复杂度为O(1)。

输入格式:

三行数据,第一行是顺序表的元素个数,第二行是顺序表的元素,第三行是x和y。

输出格式:

删除元素值在[x,y]之间的所有元素后的顺序表。

输入样例:

10
5 1 9 10 67 12 8 33 6 2
3 10

输出样例:

1 67 12 33 2
#include "iostream"
using namespace std;

int main(){
    int n;
    cin >> n; //输入第一个元素,顺序表元素的个数
    int a[n],flag=0; //定义一个数组,用flag做标记判断是否需要输出空格
    for (int i = 0; i < n; i++) { //为数组元素赋值
        cin >> a[i];
    }
    int x,y;
    cin >> x >> y;  //输入删除元素区间范围
    for (int i = 0; i < n; i++) {  //循环遍历找到删除元素范围内的值并删除,反之输出元素
        if ((a[i]<x||a[i]>y)&&flag==1)
            cout << " " << a[i];
        else if(a[i] < x || a[i] > y){
            flag = 1;
            cout << a[i];
        }
    }
//    for (int i = 0; i < n; i++) {  //循环遍历找到删除元素范围内的值并删除,反之输出元素
//        if ((a[i]<x||a[i]>y)&&flag!=1)
//            cout << a[i] << " " ;
//        else if(a[i] < x || a[i] > y){
//            flag = 1;
//            cout << a[i];
//        }
//    }
    return 0;
}
#include<stdio.h>
int main(){
    int a[10000];
    int x,y,i,t,n;
    int flag=1;
    scanf("%d",&n);
    for(i=0;i<n;i++)
        scanf("%d",&a[i]);
    scanf("%d%d",&x,&y);
    for (i=0;i<n;i++){
        if(flag){
            if(a[i]<x||a[i]>y){
                printf("%d",a[i]);
                flag=0;
            }
        }
        else{
            if(a[i]<x||a[i]>y)
                printf(" %d",a[i]);
        }
    }
    return 0;
}

jmu-ds-简单密码 (20 分)(不在范围了)

Julius Caesar曾经使用过一种很简单的密码。对于明文中的每个字符,将它用它字母表中后5位对应的字符来代替,这样就得到了密文。比如字符A用F来代替。如下是密文和明文中字符的对应关系。

密文 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

明文 V W X Y Z A B C D E F G H I J K L M N O P Q R S T U

你的任务是对给定的密文进行解密得到明文。 你需要注意的是,密文中出现的字母都是大写 字母。密文中也包括非字母的字符,对这些字符不用进行解码。

输入格式:

输入一行密文字符串,可包含空格。

输出格式:

输出明文字符串。输入明文字符串为空时,输出“NULL”

输入样例:

AB 12aC dab EF
结尾无空行

输出样例:

VW 12aX dab ZA
结尾无空行
#include "iostream"
#include "string"
using namespace std;
int main(){
    string str1;//定义一个字符串
    getline(cin,str1);  //getline获取字符串
    if (str1.size()==0){
        cout << "NULL";   //如果字符串长度为0,即是一个空串,输出NULL
        return 0;
    }
    for (int i = 0; i < str1.size(); i++) {  //逐个遍历,对明文转换
        if (str1[i]>='A'&&str1[i]<='E')
            str1[i]+=21;  //按照规则A~E在原来编码值基础上加21
        else if(str1[i]>='F'&&str1[i]<='Z')
            str1[i]-=5;   //按照规则F~Z在原来编码值基础上减5
    }
    cout<<str1;
    return 0;
}

R7-5 递增有序顺序表的插入 (20 分)

实验目的:1、掌握线性表的基本知识 2、深入理解、掌握并灵活运用线性表。3、熟练掌握线性表的存储结构及主要运算的实现 已知顺序表L递增有序,将X插入到线性表的适当位置上,保证线性表有序。。

输入格式:

第1行输入顺序表长度,第2行输入递增有序的顺序表,第3行输入要插入的数据元素X。

输出格式:

对每一组输入,在一行中输出插入X后的递增的顺序表。

输入样例:

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

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

输出样例:

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

1,3,5,6,7,9,
结尾无空行
自己的方法:
#include "iostream"
using namespace std;
int main(){
    int ascArr[1000]; //定义一个数组,将数组看作一个有序顺序表
    int a,temp;
    cin >> a; //输入顺序表长度
    for (int i = 0; i < a; i++) { //为顺序表赋值
        cin >> ascArr[i];
    }
    int insertNum;
    cin >> insertNum; //输入插入的元素
    ascArr[a] = insertNum; //将插入的元素放在数组的最后一个位置
    for (int i = a; i > 0; i--) { //调整数组顺序,使数组称为有序状态
        if (ascArr[i]<ascArr[i-1]){
            temp = ascArr[i];
            ascArr[i] = ascArr[i-1];
            ascArr[i-1] = temp;
        }
    }
    for (int i = 0; i < a+1; i++) {
        cout << ascArr[i] << ",";
    }
    return 0;
}
老师给的方法:
#include "iostream"
using namespace std;
typedef struct LNode{       //线性表元素类型定义
    int data;
    struct LNode *next;
}LNode,*LinkList;

LinkList CreateList(int n);     //声明创建线性表方法
void print(LinkList h);         //声明输出线性表方法
//插入给定数据,让插入后线性表还是有序的
void push(LinkList L,int X)
{
    LinkList r,p,q;
    p = (LinkList)malloc(sizeof(LNode));        //在内存中申请空间,p指向这个空间
    p->data = X;
    p->next = NULL;
    if(L->next == NULL)         //如果L为空
    {
        L->next = p;
    }
    else
    {
        q = L->next;
        r = L;
        while(q && q->data<X)
        {
            r = q;
            q = q->next;
        }
        if(q == NULL)
        {
            r->next = p;
        }
        else
        {
            p->next = q;
            r->next = p;
        }

    }
}
int main()
{
    LinkList Head = NULL;
    int n,x;
    cin >> n;   //输入顺序列长度n
    Head = CreateList(n);
    cin >> x;   //
    push(Head,x);
    print(Head);
    return 0;
}
//根据输入的数值,创建线性链表
LinkList CreateList(int n)
{
    LinkList L,p,q;     //定义三个指针
    int i;
    L = (LNode*)malloc(sizeof(LNode));      //创建头指针
    if(!L) return 0;
    L->next = NULL;                     //创建头结点
    q = L;          //q是一辅助变量
    for(i=0;i<n;i++)
    {
        p = (LinkList)malloc(sizeof(LNode));        //定义结点指针
        cin >> p->data;
        p->next = NULL;
        q->next = p;
        q = p;
    }
    return L;
}
//输出链表中的数据
void print(LinkList h)
{
    LinkList p = h->next;
    while(p!=NULL)
    {
        cout << p->data << ",";
        p = p->next;
    }
    cout << endl;
}
C语言写法:
#include <stdio.h>
int main(){
	int ascArr[1000];
	int a,insertNum,i,temp;
	scanf("%d",&a);
	for(i=0;i<a;i++)
		scanf("%d",&ascArr[i]);
	scanf("%d",&insertNUm);
	ascArr[a]=insertNum;
	for(i=a;i>0;i--){		
		if(ascArr[i]<ascArr[i-1]){
			temp=ascArr[i];
			ascArr[i]=ascArr[i-1];
			ascArr[i-1]=temp;
		}
    }
	for(i=0;i<a+1;i++)
		printf("%d,",ascArr[i]);	
	return 0;
}

R7-6 两个有序链表序列的合并 (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数组输入元素x,当遇见负数(-1)判定s1数组输入完毕
        s1[i++]=x;  //s1[i]=x;i++;
    }
    while(cin>>x&&x>=0) {  //向s2数组输入元素x,当遇见负数(-1)判定s2数组输入完毕
        s2[j++]=x;
    }

    if(i==0&&j==0) {  //当s1数组和s2数组都为空,即合并出来的新数组s3也为空时,输出NULL
        cout<<"NULL"<<endl;
        return 0;
    }

    int p=0,s=0;
    while(i&&j) {  //对s3数组元素进行排序,s1、s2数组都有元素的情况
        if(s1[p]<s2[s]) {
            s3[k++]=s1[p++];
            i--;
        } else {
            s3[k++]=s2[s++];
            j--;
        }
    }

    while(i) {   //对s3数组元素进行排序,s1数组有元素,s2数组为空
        s3[k++]=s1[p++];
        i--;
    }
    while(j) {   //对s3数组元素进行排序,s1数组为空,s2数组有元素
        s3[k++]=s2[s++];
        j--;
    }

    int count=0;
    for(int i=0; i<k; i++) { //在数组元组中加入空格
        if(count++)
            cout<<" ";
        cout<<s3[i];
    }
    cout<<"\n";
    return 0;
}
老师给的C语言指针写法(完全读不懂):
#include <stdio.h>
#include<stdlib.h>
typedef int ElementType;
typedef struct Node *PtrToNode;
struct Node
{
    ElementType Data;
    PtrToNode Next;         //指针定义
};
typedef PtrToNode List;
List Read();
void Print(List L);
List Merge(List L1,List L2);
int main()
{
    List L1,L2,L;
    L1 = Read();
    L2 = Read();
    L = Merge(L1,L2);
    Print(L);
    return 0;
}
//根据输入创建单链表
List Read()
{
    PtrToNode L, Head, Tail;
    Head = Tail = NULL;
    int i,x;
    for(i=0;;i++)
    {
        scanf("%d",&x);
        if(x == -1) break;
        L = (List)malloc(sizeof(struct Node));
        L->Data = x;
        L->Next = NULL;
        if(i == 0) Head = L;
        else Tail->Next = L;
        Tail = L;
    }
    return Head;        //返回头指针
}
//合并
List Merge(List L1,List L2)
{
    List L3,Head,Tail;
    Head = Tail = L3 = NULL;
    int i;
    for(i=0;;i++)
    {
        //第一种情况:L1,L2都不为NULL
        if(L1 != NULL && L2 != NULL)
        {
            //分别取出每个链表中第一个节点,比较,较小的放到新链表中,并同时修改当前节点指针
            if(L1->Data <= L2->Data)
            {
                L3 = (List)malloc(sizeof(struct Node));
                L3->Data = L1->Data;
                L3->Next = NULL;
                L1 = L1->Next;
            }
            else if(L1->Data > L2->Data)
            {
                L3 = (List)malloc(sizeof(struct Node));
                L3->Data = L2->Data;
                L3->Next = NULL;
                L2 = L2->Next;
            }
        }
        //第二种情况:L1为空,L2不为空
        else if(L1 == NULL && L2 != NULL)
        {
            L3 = (List)malloc(sizeof(struct Node));
            L3->Data = L2->Data;
            L3->Next = NULL;
            L2 = L2->Next;
        }
        //第三种情况:L2为空,L1不为空
        else if(L2 == NULL && L1 != NULL){
            L3 = (List)malloc(sizeof(struct Node));
            L3->Data = L1->Data;
            L3->Next = NULL;
            L1 = L1->Next;
        }
        //第四种情况:L1,L2都为空
        else if(L1 == NULL && L2 == NULL)
        {
            break;
        }
        
        if(i == 0) Head = L3;
        else Tail->Next = L3;
        Tail = L3;
    }
    return Head;
}
void Print(List L)
{
    PtrToNode P;
    P = L;
    int t = 0;
    if(P == NULL) printf("NULL");
    else
    {
        while(P != NULL)
        {
            t++;
            if(t != 1) printf(" ");
            printf("%d", P->Data);
            P = P->Next;
        }
    }
}

两个有序链表序列的交集 (20 分)(不在范围了)

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

输入格式:

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

输出格式:

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

输入样例:

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

输出样例:

2 
结尾无空行
四种方法,个人都不是很理解。欢迎各位大神评论或私信解题思路。
/*C++ list方法,代码量最少*/
#include <list>
#include <iostream>
using namespace std;

int main(){
    list<int>  list1;
    list<int>  list2;
    list<int>::iterator it1,it2;  //设置正向迭代器
    int val=0;
    bool flag = false;
    while(cin >> val,val!=-1)  //输入val,并且输入的val不是结束标志
        list1.push_back(val);  //C++中push_back方法在最后一个元素后增加一个新元素,同时增加容器大小。
    while(cin >> val,val!=-1)
        list2.push_back(val);

    int t = 0;
    for (it1=list1.begin(),it2=list2.begin();it1!=list1.end()&&it2!=list2.end();){
        //list1.begin()返回指向第一个元素的迭代器,list2.end()返回末尾的迭代器
        if (*it1 < *it2){
            it1++;
        }
        else if (*it1 > *it2){
            it2++;
        }else{
            if (flag)
                cout << " ";
            else
                flag = true;
            cout << *it1;
            it2++;
            it1++;
            t = 1;
        }
    }
    if (list1.empty()||list2.empty()||t==0){ //当list1为空,或list2为空,或t=0时,输出NULL
        cout << "NULL";
    }
    cout << "\n";
    return 0;
}
/*C++写法2*/
#include "iostream"
#include <cmath>
using namespace std;
#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 = nullptr;
    s2 = nullptr;
    s3 = nullptr;

    //后向插入方法
    cin >> x;
    while(x>=0){
        p=(ptr)malloc(sizeof(node));
        p->data=x;
        if (s1==nullptr) {
            p->next=s1;s1=p;last=p;
        }else{
            last->next=p;p->next=nullptr;last=p;
        }
        cin >> x;//read next
    }

    cin >> x;
    while (x>=0) {
        p=(ptr)malloc(sizeof(node));
        p->data=x;
        if (s2==nullptr) {
            p->next=s2;s2=p;last=p;
        }else{
            last->next=p;p->next=nullptr;last=p;
        }
        cin >> x;
    }
    s3=(ptr)malloc(sizeof(node));
    s3->next=nullptr;
    for (p=s1,q=s2,z=s3; p!=nullptr && q!=nullptr; ) {
        if (p->data==q->data) {
            z->next=p;
            z=z->next;
            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==nullptr||s1==nullptr)||s2==nullptr) {
        cout << "NULL";
    }else{
        p = s3->next;
        while (p!=nullptr) {
            cout << p->data;
            if (p->next!=nullptr) {
                cout << " ";
            }
            p=p->next;
        }
    }
}

/*照猫画虎的C语言写法*/
#include <malloc.h>
#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;
        }
    }
}
/*老师给的写法*/
#include <stdio.h>
#include <stdlib.h>

typedef struct Node{
    int data;
    struct Node *Next;
} *link;

link createLink()   // 向结尾处添加结点,创建单向加头链表
{
    link head, last, p;
    int x;
    head = (link)malloc(sizeof(struct Node));
    last = head;

    while( scanf("%d", &x) != EOF && x != -1 )
    {
        p = (link)malloc(sizeof(struct Node));
        p->Next = NULL;
        p->data = x;
        last->Next = p;
        last = p;
    }

    return head;
}

link Find(link p, link q)  // 寻找具有相同 data 的结点
{
    link head, last, t; // 创建一个新的头和尾巴,t 用于删除空的头结点
    /* 因为头结点为空,所以从下一个结点开始 */
    p = p->Next;
    q = q->Next;

    head = last = (link)malloc(sizeof(struct Node));
    last->Next = NULL;

    while( p )
    {
        while( q )
        {
            if( p->data < q->data )  // 如果p结点的值小于q,p向后移
            {
                break;
                // 因为第一层循环每次执行都会让p后移,所以直接退出第二层循环
            }
            else if( p->data == q->data ) // 如果结点值相同,加入尾部
            {
                link temp = (link)malloc(sizeof(struct Node));
                temp->Next = NULL;
                temp->data = p->data;
                last->Next = temp;
                last = temp;
                q = q->Next;
                break;
            }
            else // 如果p结点的值大于q,q向后移
            {
                q = q->Next;
            }
        }
        p = p->Next; // p向后移
        if( q==NULL || p==NULL ) break; // 任何一个链表指针为空即结束
    }

    last->Next = NULL;
    /* 删除头部空结点,头结点后移 */
    t = head;
    head = head->Next;
    free(t);

    return head;
}

void printLink(link p) // 输出链表值
{
    if(p == NULL)
    {
        printf("NULL");
        return ;
    }
    while(p->Next) // 如果p的下一个结点不为空,即下个结点不是结尾空结点
    {
        printf("%d ", p->data);
        p = p->Next;
    }
    printf("%d", p->data);
}

int main()
{
    link p, q, result;

    p = createLink();
    q = createLink();
    result = Find(p, q);
    printLink(result);

    return 0;
}

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

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

输入格式:

读入n及n个整数。

输出格式:

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

输入样例:

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

2
10 5
结尾无空行

输出样例:

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

10 5
结尾无空行
简单写法:
#include <iostream>
using namespace std;
int main(){
    int n;    
    cin>>n;
    int a[n];
    for(int i = 0;i<n;i++){       
        cin>>a[i];
    }    
    for(int i = 0;i<n;i++){
        if(i==0)
            cout<<a[i];
        else
            cout<< " " <<a[i];
    }
}
#include <iostream>
using namespace std;

typedef struct node{
    int data;
    struct node *next;
}linklist;

linklist *CreateListR(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));
        cin >> m;
        s->data = m;
        r->next = s;
        r = s;
    }
    r->next = NULL;
    return head;
}

int main(){
    int n;
    cin >> n;
    if (n<=0){
        return  0;
    }
    linklist *s;
    s = CreateListR(n);
    s = s->next;
    cout << s->data;
    while(s->next != NULL){
        s = s->next;
        cout <<" "<< s->data;
    }
    cout << "\n";
    return 0;
}
老师给的方法:
#include <iostream>
using namespace std;

typedef int ElemType;
typedef struct LNode
{
    ElemType data;
    struct LNode *next;
}LNode,*LinkList;

void CreateList(LinkList &L,int n)
{
    L=new LNode;
    L->next=NULL;
    LinkList r=L;
    for(int i=0;i<n;i++)
    {
        LinkList p=new LNode;
        scanf("%d",&p->data);
        p->next=NULL;
        r->next=p;
        r=p;
    }
}

void OutputList(LinkList &L)
{
    LinkList p =L->next;
    int flag=1;
    while(p)
    {
        if(flag)
        {
            printf("%d",p->data);
            flag=0;
        }
        else
        {
            printf(" %d",p->data);
        }
        p=p->next;
    }
    printf("\n");
}

int main()
{
    int n;
    LinkList L;
    scanf("%d",&n);
    CreateList(L,n);
    OutputList(L);
}

R7-8 在有序链表中插入数据 (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 <iostream>
using namespace std;

typedef int ElemType;
typedef struct LNode        //结构体定义
{
    ElemType data;
    struct LNode* next;
} LNode, * LinkList;

//创建链表
void CreateList(LinkList& L, int n)
{
    L = new LNode;      //创建头结点
    L->next = NULL;
    LNode* p = L;
    int m;
    for (int i = 0; i < n; i++)       //把输入整数组成链表
    {
        cin >> m;
        p->next = new LNode;
        p = p->next;
        p->data = m;
        p->next = NULL;
    }
}

void InsertList(LinkList& L, int n, int x)
{
    LNode* p = L;
    //第一种情况,链表为空,这种情况下是为空链表直接插入节点的
    if (p->next == NULL)        
    {
        LNode* q = new LNode;
        q->data = x;
        q->next = NULL;
        p->next = q;
        p = q;
        return;
    }
    //第二种情况,链表不为空,且要插入的元素正确位置应该在链表中间,(就是最后一个元素的前面)
    while (p->next != NULL)
    {
        LNode* temp = p;
        p = p->next;
        if (p->data == x) return;
        if (p->data > x)       //如果队列中有比X更大的数,则插入到链表中间
        {
            LNode* q = new LNode;
            q->data = x;
            q->next = p;
            temp->next = q;
            return;
        }
    }
    //第三种情况,链表不为空,但链表中所有元素都小于要插入的元素。
    LNode* q = new LNode;       //否则,插入到链表最后
    q->data = x;
    q->next = NULL;
    p->next = q;
    p = q;
    return;

}

void OutputList(LinkList L)
{
    LNode* p = L->next;
    while (p != NULL) {
        cout << p->data;
        if (p->next != NULL)
            cout << " ";
        p = p->next;
    }
}

int main()
{
    int n, x;
    cin >> n;
    LinkList L;
    CreateList(L, n);

    cin >> x;
    InsertList(L, n, x);
    OutputList(L);
    return 0;
}
之前做作业时候从网上找的写法:
#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;
}
  • 5
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小飞睡不醒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值