上机二——单链表

1.创建有序单链表

【问题描述】为从键盘终端输入的m个整数创建带头结点的有序单链表存储结构,使输入的数据元素在单链表中按照元素值递增有序。

【输入形式】

第一行:单链表中元素个数m

第二行:单链表中的m个整数

【输出形式】

按递增有序形式输出m个整数

【样例输入】

5

1 3 2 4 5

【样例输出】

1 2 3 4 5

【样例说明】

【评分标准】

#include <iostream>
using namespace std;
struct Node {
    int data;
    Node *next;
};
typedef Node *LinkList;
void createOList(LinkList &L,int m)
{
    int num,i=0,s[m];
    while(cin>>num)
    {
        s[i++]=num;
    }
    for(int i=0;i<m-1;i++)
    {
        for(int j=i+1;j<m;j++)
        {
            if(s[i]>s[j])
            {
                int t=0;
                t=s[i];
                s[i]=s[j];
                s[j]=t;
            }
        }
    }

    Node  *p,*r;
    L=new  Node;
    L->next=NULL;
    r=L;
    i=0;
    while(m)
    {
        p=new  Node;
        p->data=s[i++];
        r->next=p;
        r=p;
        m--;
    }
    r->next=NULL;
}
void printList(LinkList L) {
    Node *p;
    p=L->next;
    while(p) {
        cout<<p->data<<" ";
        p=p->next;
    }
    cout<<endl;
}
int main() {
    LinkList L;
    int m;
    cin>>m;//单链表中元素个数
    createOList(L,m);//创建带头节点的有序单链表
    printList(L);
    return 0;
}


2.输出单链表中的数据并统计单链表中的元素个数

【问题描述】下面程序中createList函数的功能是创建若干个整数的带头结点的单链表存储结构。getLength函数的功能是求解单链表中元素的个数,printLst函数的功能是将单链表中各个整数以空格间隔顺序输出。根据上下文,将程序补充完整。

【输入形式】若干整数以空格间隔

【输出形式】两行。第一行:单链表中的整数以空格间隔输出;第二行:单链表中元素的个数

【样例输入】1 2 3 4 5

【样例输出】

1 2 3 4 5

5

【样例说明】

【评分标准】

#include <iostream>
#include <cstdlib>
using namespace std;
struct LNode
{
    int data;
    LNode *next;
};
void createList(LNode *&h)
{
    int num;
    LNode *p,*r;
    h=new LNode;
    h->next=NULL;
    r=h;
    while(cin>>num)
    {
        p=new LNode;
        p->data=num;
        r->next=p;
        r=p;
    }
    r->next=NULL;
}

int  getLength(LNode *&L)
{
        LNode  *p;
        int length=0;
        p=L->next;
        while(p)  {
                p=p->next;
                length++;
        }
        return length;
}
void printList(LNode *&L)
{
    LNode  *p;
        p=L->next;
        while(p)  {
                cout<<p->data<<" ";
                p=p->next;
        }
        cout<<endl;
}

int main()
{
    LNode *L;
    createList(L);
    printList(L);
    cout<<getLength(L);
    return 0;
}


3.删除单链表中相同元素

【问题描述】单链表中存放了若干整数,请删除相同整数。

【输入形式】单链表

【输出形式】删除相同整数后的单链表

【样例输入】1 1 1 2 3

【样例输出】1 2 3

【样例说明】以递增的形式输入数据,允许相同元素

【评分标准】

#include <stdlib.h>
#include <iostream>
using namespace std;
//类型定义
#include <stdlib.h>
struct LNode
{
    int data;
    LNode *next;
};
typedef LNode *LinkList;

//尾插入法创建单链表
void createList(LinkList &h, int n)
{
    h = new LNode;
    h->next = NULL;
    LNode *p, *r;
    r = h;
    for (int i = 1; i <= n; i++)
    {
        p = new LNode;
        cin>>p->data;
        r->next = p;
        r = p;
    }
    r->next = NULL;
}
void printList(LinkList h)
{
    LNode *p=h->next;
    while(p)
    {
        cout<<p->data<<" ";
        p=p->next;
    }
    cout<<endl;
}

void listDeleteRepeat(LinkList h)
{
    LNode *p=h->next;
    while(p)
    {
        LNode *q=p;
        while(q->next)
        {
            if(q->next->data==p->data)
            {
                LNode *tmp=q->next;
                q->next=q->next->next;
                delete tmp;
            }
            else{
                q=q->next;
            }
        }
        p=p->next;
    }
}

int main()
{
    LinkList h;
    createList(h, 5);
    listDeleteRepeat(h);
    printList(h);
    return 0;
}

4.删除单链表中某区间的数

【问题描述】已知某带头结点的单链表中存放着若干整数,请删除该单链表中元素在[x, y]之间的所有结点,要求算法的时间复杂度为O(n),空间复杂度为O(1)。

【输入形式】第一行:单链表中元素个数m

第二行:单链表中的m个整数

第三行:要删除的元素值所在区间[x,y]对应的x和y

【输出形式】

删除元素后的单链表中剩下的元素值

【样例输入】

5

13 24 50 33 56

30 50

【样例输出】

13 24 56

【样例说明】

【评分标准】

#include <iostream>
using namespace std;
struct Node {
    int data;
    Node *next;
};
typedef Node *LinkList;
void createList(LinkList &L,int n) {
    Node *p,*r;
    L=new Node;
    L->next=NULL;
    r=L;
    for(int i=1; i<=n; i++) {
        p=new Node;
        cin>>p->data;
        r->next=p;
        r=p;
    }
    r->next=NULL;
}
void printList(LinkList L) {
    Node *p;
    p=L->next;
    while(p) {
        cout<<p->data<<" ";
        p=p->next;
    }
    cout<<endl;
}
void delElem(LinkList h,int a,int b)
{
    Node *p,*c;
    p=h,c=h->next;//c为p的下一个结点
    while(c)
    {
        if(c->data>=a&&c->data<=b)
        {
            p->next=c->next;
            delete c;
            c=p->next;
        }
        else
        {
            p=p->next;
            c=c->next;
        }
    }
}
int main() {
    LinkList L;
    int m;
    int x,y;
    cin>>m;//单链表中元素个数
    createList(L,m);//尾插入法创建带头节点的单链表
    cin>>x>>y;//要删除的元素值所在区间[x,y],包含x和y
    delElem(L,x,y);//删除单链表中x-y之间的数
    printList(L);//输出结果单链表中的所有数据
    return 0;
}


5.倒数第k个元素

【问题描述】已知带头结点的非空单链表中存放着若干整数,请找出该链表中倒数第k个元素。

【输入形式】第一行:单链表中元素个数m

第二行:单链表中的m个整数

第三行:k值

【输出形式】倒数第k个元素的值(不存在倒数第k个元素输出"no")

【样例输入】

5

13 24 50 33 56

2

【样例输出】

33

【样例说明】

输入:

5

13 24 50 33 56

6

输出:no

【评分标准】

#include <iostream>
using namespace std;
struct Node {
    int data;
    Node *next;
};
typedef Node *LinkList;
void createList(LinkList &L,int n) {
    Node *p,*r;
    L=new Node;
    L->next=NULL;
    r=L;
    for(int i=1; i<=n; i++) {
        p=new Node;
        cin>>p->data;
        r->next=p;
        r=p;
    }
    r->next=NULL;
}
void printList(LinkList L) {
    Node *p;
    p=L->next;
    while(p) {
        cout<<p->data<<" ";
        p=p->next;
    }
    cout<<endl;
}
Node *getElem(LinkList L,int k)
{
    int count=0;
    Node *p,*a;
    p=L->next;//p指向第二个结点
    a=L->next;
    while(p)
    {
        if(count<k)
            count++;
        else
            a=a->next;
        p=p->next;
    }
    if(count==k)
        return a;
    else
        return 0;
}
int main() {
    LinkList L;
    int m,k;
    cin>>m;//单链表中元素个数
    createList(L,m);//尾插入法创建带头节点的单链表
    cin>>k;
    Node *p=getElem(L,k);//找单链表中倒数第k个元素
    if(p)
        cout<<p->data;
    else
        cout<<"no";
    return 0;
}

6.查找两个单链表的公共结点

【问题描述】给定两个单链表,编写算法找出两个链表的公共结点

【输入形式】用于构造两个公共链表的结点数和数据元素的值

【输出形式】两个单链表所有公共结点的元素值以空格间隔输出

【样例输入】若构建的两个链表结构如下图所示:则公共结点为数据值为11和15的结点。

【样例输出】11 15

【样例说明】

【评分标准】

#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
struct LNode
{
    int data;
    LNode *next;
};
typedef LNode *Linklist;
void create(Linklist &h,int n)
{
    LNode *r,*p;
    h=new LNode;
    h->next=NULL;
    r=h;
    for(int i=1; i<=n; i++)
    {
        p=new LNode;
        cin>>p->data;
        r->next=p;
        r=p;
    }
    r->next=NULL;
}

void create(Linklist &h)
{
    LNode *r,*p;
    srand(time(NULL));
    int i,m;
    m=rand()%10;
    h=new LNode;
    h->next=NULL;
    r=h;
    for(int i=1; i<=m; i++)
    {
        p=new LNode;
        p->data=rand()%90+10;
        r->next=p;
        r=p;
    }
    r->next=NULL;
}


LNode *getTail(Linklist h)
{
    LNode *tail;
    tail=h;
    while(tail->next)
    {
        tail=tail->next;
    }
    return tail;
}

void connect(Linklist ha,Linklist hb)
{
    LNode *r;
    r=getTail(ha);
    r->next=hb->next;
}

void printList(Linklist h)
{
    LNode *p=h->next;
    while(p)
    {
        cout<<p->data<<" ";
        p=p->next;
    }
    cout<<endl;
}

void printPublicNode(Linklist ha, Linklist hb)
{
    LNode *pa = ha->next;
    while (pa)
    {
        LNode *pb = hb->next;
        while (pb)
        {
            if (pa == pb)
            {
                cout << pa->data << " ";
                break;
            }
            pb = pb->next;
        }
        pa = pa->next;
    }

}


int main()
{
    Linklist ha,hb,hc;
    int n;
    cin>>n;
    create(ha);
    create(hb);
    create(hc,n);
    connect(ha,hc);
    connect(hb,hc);
    printPublicNode(ha,hb);
    return 0;
}

7.有序集合的并集-无重复数据-单链表

【问题描述】将两个递增的有序链表合并为一个递增的有序链表。要求结果链表仍使用原来的两个链表的存储空间,不另外占用其他的存储空间。表中允许有重复的数据。

【输入形式】三行,第一行:两个有序链表中元素的个数,第二行:第一个链表中的元素以空格间隔,第三行:第二个链表中的元素以空格间隔

【输出形式】合并后的没有重复元素的有序链表中的数据以空格间隔

【样例输入】

3 4

1 5 7

2 4 7 9

【样例输出】1 2 4 5 7 9

【样例说明】

【评分标准】

#include <bits/stdc++.h>
using namespace std;
struct OLNode
{
    int data;
    OLNode *next;
};
typedef OLNode *OLinkList;
OLNode *getPre(OLinkList h,int e)
{
    OLNode *pre=h;
    while(pre->next&&pre->next->data<e)
        pre=pre->next;
    return pre;
}
void createOLinkList(OLinkList &h,int n)
{
    h=new OLNode;
    h->next=NULL;
    OLNode *pre,*p;
    int e;
    for(int i=1; i<=n; i++)
    {
        cin>>e;
        p=new OLNode;
        p->data=e;
        pre=getPre(h,e);
        p->next=pre->next;
        pre->next=p;
    }
}
void printOLinkList(OLinkList h)
{
    OLNode *p;
    p=h->next;
    while(p)
    {
        cout<<p->data<<" ";
        p=p->next;
    }
    cout<<endl;
}
void olistUnion(OLinkList ha, OLinkList hb)
{
    OLinkList h = ha;
    OLinkList p = ha->next;
    OLinkList q = hb->next;
    while (p && q) {
        if (p->data < q->data) {
            h->next = p;
            h = p;
            p = p->next;
        }
        else if (p->data > q->data) {
            h->next = q;
            h = q;
            q = q->next;
        }
        else {
            // 两个节点的数据相等,保留一个节点并删除另一个节点
            h->next = p;
            h = p;
            p = p->next;
            OLinkList tmp = q->next;
            delete q;
            q = tmp;
        }
    }
    h->next = p ? p : q;    // 将剩余部分接入新链表
    delete hb;   // 释放链表hb的头结点
}

int main()
{
    int m,n;
    OLinkList ha,hb;
    cin>>m>>n;
    createOLinkList(ha,m);
    createOLinkList(hb,n);
    olistUnion(ha,hb);
    printOLinkList(ha);
    return 0;
}


8.有序集合的并集-单链表

【问题描述】将两个递增的有序链表合并为一个递增的有序链表。要求结果链表仍使用原来的两个链表的存储空间,不另外占用其他的存储空间。表中允许有重复的数据。

【输入形式】三行,第一行:两个有序链表中元素的个数,第二行:第一个链表中的元素以空格间隔,第三行:第二个链表中的元素以空格间隔

【输出形式】合并后的没有重复元素的有序链表中的数据以空格间隔

【样例输入】

3 4

1 5 7

2 4 7 9

【样例输出】1 2 4 5 7 7 9

【样例说明】

【评分标准】

#include <bits/stdc++.h>
using namespace std;
struct OLNode
{
    int data;
    OLNode *next;
};
typedef OLNode *OLinkList;
OLNode *getPre(OLinkList h,int e)
{
    OLNode *pre=h;
    while(pre->next&&pre->next->data<e)
        pre=pre->next;
    return pre;
}
void createOLinkList(OLinkList &h,int n)
{
    h=new OLNode;
    h->next=NULL;
    OLNode *pre,*p;
    int e;
    for(int i=1; i<=n; i++)
    {
        cin>>e;
        p=new OLNode;
        p->data=e;
        pre=getPre(h,e);
        p->next=pre->next;
        pre->next=p;
    }
}
void printOLinkList(OLinkList h)
{
    OLNode *p;
    p=h->next;
    while(p)
    {
        cout<<p->data<<" ";
        p=p->next;
    }
    cout<<endl;
}
void olistUnion(OLinkList ha, OLinkList hb)
{
    OLinkList h = ha;
    OLinkList p = ha->next;
    OLinkList q = hb->next;
    while (p && q) {
        if (p->data <= q->data) {
            h->next = p;
            h = p;
            p = p->next;
        }
        else if (p->data > q->data) {
            h->next = q;
            h = q;
            q = q->next;
        }
        
    }
    h->next = p ? p : q;    // 将剩余部分接入新链表
    delete hb;   // 释放链表hb的头结点
}
int main()
{
    int m,n;
    OLinkList ha,hb;
    cin>>m>>n;
    createOLinkList(ha,m);
    createOLinkList(hb,n);
    olistUnion(ha,hb);
    printOLinkList(ha);
    return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值