基础数据结构之链表的创建(包括约瑟夫问题)

基础数据结构之链表的创建

0 - 链表

(1)存储类型不限,存储单元不连续
(2)操作:初始化,添加,遍历,插入,删除,查找,排序,释放等
(3)单向/双向,循环
(4)注意头结点位置不变(一般情况下都是的)

关于结构体指针:http://t.csdn.cn/mgBru

1. 动态单向链表:

  • 临时分配链表节点 ---- 释放
  • 创建过程:声明(node*) – 分配空间(new node) – 初始化(NULL)
//动态创建单向循环链表
#include<bits/stdc++.h>
using namespace std;

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

int main()
{
    int n = 10;   // 结点数目
    node* head=new node; head->data=1; head->next=NULL;   // 为头结点分配空间,并初始化
    
    node* pNew,*p;  // pNew 是当前结点---用来添加结点,p是现在这个链表所指向的结点
    p=head;   //链表首先指向头部
    p->next=NULL;   //初始化结构体指针p----变量使用之前要初始化完

    for(int i=2;i<=n;i++)
    {
        pNew=new node;   //先分配空间
        pNew->data=i;    //后初始化
        pNew->next=NULL;

        p->next=pNew;   //将pNew结点加入链表中
        p=p->next;  //p指向当前链表的最新结点
    }

    p->next = head; //末尾的下一个连接头部,构成循环链表
    p=head;    //指针回到头部

    //测试一下
    for(int i=0;i<n;i++)
    {
       cout<<p->data<<endl;
       p=p->next;
    }

    return 0;
}


2. 静态链表:

  • 空间大小已经提前分配好
  • 对内存要求不严格,可以加快编码速度

2.1 单向

//创建单向静态循环链表
#include<bits/stdc++.h>
const int N=101;

struct node{
    int id;
    int nextid;  //指向下一个结点的id
    //int data;  如果有数据,根据实际情况添加
}Node[N];

int main()
{
    int n=10;
    for(int i=1;i<n;i++)
    {
        Node[i].id=i;
        Node[i].nextid=i+1;
    }
    Node[n].id=n;
    Node[n].nextid=1;  //Node[10]=1 --- 尾端的结点指向头部,构成循环链表

    int now=1;
    for(int i=1;i<2*n;i++)
    {
        printf("%d ",Node[now].id);
        now=Node[now].nextid;
    }
    
    
}

2.2 双向

#include<bits/stdc++.h>
const int N=101;

struct node{
    int id;
    int nextid;  //指向下一个结点的id
    int previd;  //指向前一个结点的id
}Node[N];

int main()
{
    int n=10;

    for(int i=1;i<n;i++)
    {
        Node[i].id=i;
        Node[i].nextid=i+1;
        Node[i].previd=i-1;
    }
    Node[1].previd=n;    //头部结点的前一个结点为尾部结点
    Node[n].id=n;
    Node[n].previd=n-1;
    Node[n].nextid=1;  //Node[10]=1 --- 尾端的结点指向头部,构成循环链表

    //测试一下
    int now=1;
    for(int i=1;i<2*n;i++)
    {
        printf("%d ",Node[now].id);
        now=Node[now].nextid;
    }

    return 0;
}

2.3 用一位数组实现单向静态链表

//一位数组实现单向静态循环链表
#include<bits/stdc++.h>
const int N=101;

int Nodes[N];

int main()
{
    int n=10;
    for(int i=1;i<n;i++)
    {
        Nodes[i]=i+1;     //结点的数据表示的是下一个结点的索引
    }
    Nodes[n]=1;   //结尾指向头部,构成循环链表

    //测试一下
    int now=1;
    for(int i=1;i<2*n;i++)
    {
        printf("%d ",Nodes[now]);
        now=Nodes[now];
    }

    return 0;
}




约瑟夫问题

题目描述

n n n 个人围成一圈,从第一个人开始报数,数到 m m m 的人出列,再由下一个人重新从 1 1 1 开始报数,数到 m m m 的人再出圈,依次类推,直到所有的人都出圈,请输出依次出圈人的编号。

注意:本题和《深入浅出-基础篇》上例题的表述稍有不同。书上表述是给出淘汰 n − 1 n-1 n1 名小朋友,而该题是全部出圈。

输入格式

输入两个整数 n , m n,m n,m

输出格式

输出一行 n n n 个整数,按顺序输出每个出圈人的编号。

样例 #1

样例输入 #1

10 3

样例输出 #1

3 6 9 2 7 1 8 5 10 4

提示

1 ≤ m , n ≤ 100 1 \le m, n \le 100 1m,n100

动态创建链表

//替换掉测试部分即可
    while((n--)>=1)
    {
        for(int i=1;i<m;i++)
        {
            prev=now;                 //用prev记录前一个指针
            now=now->next;
        }

        printf("%d ",now->data);
        prev->next=now->next;
        now=prev->next;
    }

静态数组创建单向循环列表

//替换掉测试部分即可
    int prev=1,now=1;
    while((n--)>=1)
    {
        for(int i=1;i<m;i++)   //数了两下
        {
            prev=Node[now].id;
            now=Node[now].nextid;
        }
        //第三下开始踢人i
        printf("%d ",now);
        now=Node[now].nextid;   //now指向i的下一个结点
        Node[prev].nextid=now;   //前一个结点的下一个指向i的下一个
    }

    return 0;

一位数组创建单向循环链表

//替换掉测试部分即可
    int now=1,prev=1;

    while((n--)>=1)
    {
        for(int i=1;i<m;i++)
        {
            prev=now;
            now=arr[now];
        }
        printf("%d ",now);
        arr[prev]=arr[now];
        now=arr[prev];
    }

    return 0;
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值