数据结构期末复习-单链表代码案例

单链表引言

✈️ 定义
单链表是一种由多个节点组成的线性结构,每个节点包含两个部分

  1. 数据域(data):存储具体的数据元素;

  2. 指针域(next):存储指向下一个节点的指针。

整个链表通过首节点开始,逐个指向后继节点,最后一个节点的 next 指针为空(NULL),表示链表结束。

操作描述时间复杂度
初始化创建一个空链表(通常建立头结点)O(1)
插入在指定位置插入新节点O(n)
删除删除指定位置的节点O(n)
查找查找第一个匹配值的节点O(n)
遍历从头到尾依次访问每个节点O(n)

适用场景

1)元素数量不固定、需频繁插入/删除的场景;

2)空间受限,无法一次性分配大块内存的情况;

3)操作顺序与访问方向固定(从头到尾)的应用。

优点

  • 插入、删除操作灵活,只需改变指针,不需要移动元素;

  • 空间利用率高,不需要预分配连续内存;

  • 易于实现动态扩展。

⌛️缺点

  • 不能随机访问,访问某个位置的元素必须从头遍历;

  • 指针域额外占用存储空间;

  • 操作复杂性较高,容易出错(尤其是指针操作)。

1.单链表的创建

【问题描述】随机输入一些数据,请采用尾插法创建一个带头结点的单链表,将数据存入,然后顺序遍历该单链表并输出数据,以查看是否创建成功。

【样例输入】6 3 5 2 9 0

【样例输出】6 3 5 2 9

  备注:0代表输入结束

#include<iostream>
#include<stdlib.h>
#define Size 10
using namespace std;
typedef struct LNode
{
    int data;
    struct LNode *next;
}LNode,*LinkList;

int add(LinkList &L)
{
    L=(LinkList)malloc(sizeof(LNode));
    LNode *s,*r;
    r=L;
    int flag=0;
    while(1)
    {
        int x;
        cin>>x;
        if(x==0)
            break;
        s=(LinkList)malloc(sizeof(LNode));
        s->data=x;
        r->next=s;
        r=s;
        flag++;

    }
    return flag;

}

void shuchu(LinkList &L,int i)
{
    LNode *p;
    int j=0;
    p=L;
    while(p!=NULL&&j<i)
    {
        cout<<p->next->data<<' ';
        p=p->next;
        j++;
    }
}

int main()
{
    LinkList L;
    int i=add(L);
    shuchu(L,i);
    return 0;
}

 2.单链表的变化

【问题描述】设线性表L={a1,a2,a3,...,an-2,an-1,an}采用带头结点的单链表保存,请设计一个空间复杂度为O(1)且时间上尽可能高效的算法,重新排列L中的各结点,得到线性表L'={a1,an,a2,an-1,a3,an-2,...)

【样例输入】1 2 3 4 5 0

【样例输出】1 5 2 4 

#include<iostream>
#include<stdlib.h>
using namespace std;

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

int creat(LinkList &L)
{
  L=(LNode*)malloc(sizeof(LNode));
  L->next=L;
  L->prior=L;
  LNode *r,*s;
  r=L;
  int flag=0;
  while(1)
  {
    int x;
    cin>>x;
    if(x==0)
      break;
    s=(LNode*)malloc(sizeof(LNode));
    s->data=x;
    r->next=s;
    s->prior=r;
    r=s;
    flag++;
  }
  r->next=L;
  L->prior=r;
  return flag;
}

void pailie(LinkList &L,int flag)
{
  LNode *r,*p;
  p=L->next;
  r=L;
  while(r->next!=L)
    r=r->next;
  for(int i=0;i<flag/2;i++)
  {
    cout<<p->data<<' '<<r->data<<' ';
    p=p->next;
    r=r->prior;
  }
  if(flag%2==1)
  cout<<p->data;
}

int main()
{
  LinkList L;
  int flag=creat(L);
  pailie(L,flag);
  return 0;
}

 3.等值字串

【问题描述】如果字符串的一个子串(其长度大于1)的各个字符均相同,则称之为等值子串。试设计一算法,求出串S中一个长度最大的等值子串;如果串S 中不存在等值子串,则输出信息no

【输入形式】输入一个字符串,并以!结束

【输出形式】输出第一个出现的最长字符串,如果没有输出no

【样例输入】aabc123abc123cc!

【样例输出】aa

#include<iostream>
#include<stdlib.h>
using namespace std;

typedef struct LNode
{
  char data;
  struct LNode *next;
}LNode,*LinkList;

void init(LinkList &L)
{
    L=(LNode *)malloc(sizeof(LNode));
    L->next=NULL;
}

int input(LinkList &L)
{
    char x;
    LNode *s,*r;
    r=L;
    int flag=0;
    while(1)
    {
       cin>>x;
       if(x=='!')
        break;
       s=(LNode *)malloc(sizeof(LNode));
       s->data=x;
       r->next=s;
       r=s;
       flag++;
    }
    return flag;
}

void found(LinkList &L,int flag)
{
    LNode *r,*s;
    r=L->next;
    int n=flag;
    int a[10000];
    for(int i=0;i<n;i++)
    {
       s=r->next;
       int x=1;
       for(int j=0;j<n-i-1;j++)
       {
          if(r->data==s->data)
         {
           x++;
           s=s->next;
         }
          else
         {
           break;
         }
       }
       a[i]=x;
       r=r->next;
    }
    int max=a[0];
    int y=0;
    for(int i=0;i<n;i++)
    {
        if(a[i]>max)
        {
            max=a[i];
            y=i;
        }
    }
    r=L;
    for(int i=0;i<y+1;i++)
    {
        r=r->next;
    }
    if(max!=1)
    {
        for(int i=0;i<max;i++)
        cout<<r->data;
    }
    else
        cout<<"no";
}

int main()
{
    LinkList L;
    init(L);
    int flag=input(L);
    found(L,flag);
    return 0;
}

 4.单链表结点的删除

bool delete(LNode *p)   //删除指定结点p
{
    if(p==NULL)
        return false;
    LNode *q=p->next;   //q指向*p的后继结点
    p->data=p->next->data;   //和后继结点交换数据域
    p->next=q->next;    //将*q结点从链中“断开”
    free(q);
    return true;
}

5.单链表的按值查找

LNode *locate(LinkList L,int e)  //寻找数据为e的结点
{
    LNode *p=L->next;  //从第一个结点开始查找数据为e的结点
    while(p!=NULL&&p->data!=e)
        p=p->next;
    return p;  //找到后返回该结点的指针,否则返回NULL;
}

6.头插法建立单链表

LinKList create(LinkList &L)  //头插法本质——元素逆置
{
    LNode *s;
    int x;
    L=(LinkList)malloc(sizeof(LNode));  //创建头结点
    L->next=NULL;
    while(1)
    {
        cin>>x;
        if(x==0)
            break;  //输入0表示结束
        s=(LNode*)malloc(sizeof(LNode));
        s->data=x;
        s->next=L->next;
        L->next=s;  //L为头指针
    }
    return L;
}

⛳ 你好哇,我是小瑾,是一名在校大学生~

⛵目前博文包含课程设计、csp刷题、算法介绍、当下科技热点分享、网站软件推荐等等哦,还会更新学习到的深度学习、视觉等方面的知识~(如果发现你和博主是一个学校,那么仔细找找,也许会找到许多你需要的东西✌️)

⛄一个希望与大家携手共进的小博主

✍关注我,让你的代码之旅不再孤独!  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小瑾比个耶

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

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

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

打赏作者

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

抵扣说明:

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

余额充值