数据结构笔记--线性表

线性表

(linear list)简称表,是n(n≥0)个具有相同类型的数据元素的有限序列。

顺序表

——线性表的顺序存储结构

  • 只要确定了存储顺序表的起始地址,计算任意一个元素的存储地址的时间是相等的,具有这种特点的存储结构称为随机存储结构
  • 存储结构定义
const int MaxSize = 10;
typedef int DataType;
typedef struct
{
    DataType data[MaxSize];
    int length;
} SeqList;
  • 简单实现
// 初始化
void InitList(SeqList &L)
{
    L.length = 0;
}
// 创建,根据数组a创建长度为n的顺序表
void CreateList(SeqList &L, DataType a[], int n)
{
    int i;
    if(n > MaxSize) {
        printf("参数非法!");
        exit(-1);
    }
    for(i = 0; i < n; i++)
    {
        L.data[i] = a[i];
    }
    L.lenght = n;
}
// 按位、值查找
DataType GetData(SeqList &L, int i)
{
    if(i<1 || i>L.length) {
        printf("查找位置非法")
        exit(-1);
    }
    return L.length[i]
}
int LocateData(SeqList &L, DataType d)
{
    int i;
    for(i = 0; i < L.length; i++)
    {
        if (L.data[i] == d)
            return i+1; // 返回位置(第几个)
    }
    return 0; // 没有找到
}
// 插入
void Insert(SeqList &L, int i, DataType d)
{
    if(L.length >= MaxSize) {
        printf("上溢");
        exit(-1);
    }
    if(i < 1 || i > L.length) {
        print("位置错误");
        exit(-1);
    }
    int j;
    for(j = L.length; j>= i; j--)
        L.data[j] = L.data[j-1];
    L.data[i-1] = d;
    L.length++;
}
// 删除第i个元素
DataType Delete(SeqList &L, int i)
{
    if (L.length == 0) {
        printf("下溢");
        exit(-1);
    }
    if (i < 1 || i > L.length) {
        printf("删除位置错误");
        exit(-1);
    }
    int j;
    DataType d = L.data[i-1];
    for(j = i; j < L.length; j++)
        L.data[j-1] = L.data[j];
    L.length--;
    return d;
}

单链表

  • 简单定义:使用一组任意的存储单元存放线性表的元素,存储单元即可以是连续的也可以是不连续的,可以分散在内存的任意位置。
    带有头结点的单链表
  • 存储结构
typedef int DataType;
typedef struct Node
{
    DataType data;
    Node *next;
} Node, *first;
  • 简单实现
// 初始化
Node* InitList(Node * first)
{
    first = (Node *)malloc( sizeof( Node ) );
    first->next = NULL;
    return first;
}
// 遍历
void PrintList(Node *first)
{
    p = first->next;
    whilh (p != NULL) {
        print(p->data);
        p = p->next;
    }
}
// 按位、值查找
DataType GetData(Node *first, int i)
{
    p = first->next;
    int count = 1;
    while(p != NULL && count < i) {
        p = p->next;
        count++;
    }
    if(p == NULL) { 
        printf("查找失败");
        exit(-1);
    } else {
        return p->next;
    }
}
int Locate(Node *first, DataType d)
{
    p = first->next;
    int count = 1;
    while(p != NULL) {
        if(p->data == d)
            return count;
        p = p->next;
        count++;
    }
    return 0;
}
// 插入
void Insert(Node *first, int i, DataType d)
{
    p = first;
    int count = 0;
    while(p != NULL && count < i-1) {
        p = p->next;
        count++;
    }
    if(p == NULL) {
        printf("插入失败");
        exit(-1);
    } else {
        Node *s;
        s = (Node *)malloc( sizeof(Node) );
        s->data = d;
        s->next = p->next;
        p->next = s;
    }
}
// 删除
DataType Delete(Node *first, int i)
{
    p = first;
    int count = 0;
    while(p != NULL && count < i-1) {
        p = p->next;
        count++;
    }
    if(p == NULL || p->next == NULL) {
        printf("删除失败");
        exit(-1);
    } else {
        Node *q;
        DataType d;
        q = (Node *)malloc( sizeof(Node) );
        q = p->next;
        d = p->data;
        p->Next = q->next;
        free(q);
        return d;
    }
}
// 头插法建立单链表
Node* Create(Node *first, DataType a[], int n)
{
    first = (Node *)malloc( sizeof(Node) );
    first->next = NULL;
    int i;
    for(i = 0; i < n; i++)
    {
        Node *s;
        s = (Node *)malloc( sizeof(Node) );
        s->data = a[i];
        s->next = first->next;
        first->next = s;
    }
    return first;
}
// 尾插法建立单链表
Node* Create(Node *first, DataType a[], int n)
{
    first = (Node *)malloc( sizeof(Node) );
    Node *r;
    r = first;
    int i;
    for(i = 0; i < n; i++)
    {
        Node *s;
        s = (Node *)malloc( sizeof(Node) );
        s->data = a[i];
        r->next = s;
        r = s;
    }
    r->next = NULL;
    return first;
}

双链表

  • 在单链表的基础上设置一个前驱节点
    双链表的结构
  • 存储结构定义
typedef int DataType;
typedef struct DulNode
{
    DataType data;
    DulNode *prior, *next
} DulNode, *first;
  • 简单实现
// 插入
void Insert(DulNode *first, int i, DataType d)
{
    Node *p;
    p = first;
    int count = 0;
    while(p != NULL && count < i-1) {
        p = p->next;
        count++;
    }
    if(p == NULL) {
        printf("插入失败");
        exit(-1);
    } else {
        Node *s;
        s = (Node *)malloc( sizeof(Node) );
        s->data = d;
        s->prior = p;
        s->next = p->next;
        p->next->prior = s;
        p->next = s;
    }   
}
// 删除
DataType Delete(Node *first, int i)
{
    Node *p;
    p = first;
    int count = 0;
    while(p != NULL && count < i) {
        p = p->next;
        count++;
    }
    if(p == NULL) {
        printf("删除失败");
        exit(-1);
    } else {
        Node *q;
        DataType d;
        q = p->next;
        d = q->data;
        (p->prior)->next = p->next;
        (p->next)->prior = p->prior;
        free(q);
        return d;
    }
}

循环链表

  • 循环单链表
    这里写图片描述
  • 循环双链表
    这里写图片描述

静态链表

  • 用数组来表示单链表,用数组下标来模拟单链表的指针
    这里写图片描述
  • 存储结构定义
const int MaxSize = 10;
typedef int DataType;
typedef struct
{
    DataType data;
    int next;
} SNode, SList[MaxSize];
  • 简单实现
// 插入
s = avail;
avail = SList[avail].next;
Slist[s].data = d;
SList[s].next = SList[p].next;
SList[p].next = s
// 删除
q = SList[p].next;
Slist[p].next = SList[q].next;
SList[q].next = avail;
avail = q;

约瑟夫环问题

  • 问题描述
    约瑟夫环问题由古罗马史学家约瑟夫提出,他参加并记录了公元66-70年犹太人反抗罗马帝国的起义。在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。
    约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。
  • C++实现
#include<iostream>
#include<list>
#include<cstdlib>
int main()
{
    int total=0;
    int key=0;
    cout<<"input total:";
    cin>>total;
    cout<<"input key:";
    cin>>key;
    if(key>total || key <1||total <1)
    {
        cout<<"error input!"<<endl;
    }
    list<int>* table = new list<int>();
    for(int i =1;i<=total;++i)
        table->push_back(i);
    int shout = 1;
    for(list<int>::iterator it=table->begin();table->size()!=1;)
    {
        if(shout++==key) {
            it = table->erase(it);
            shout=1;
        } else {
            ++it;
        }
        if(it==table->end()) {
            it=table->begin();
        }
    }
    cout<<"the last one:";
    cout<<*table->begin()<<endl;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值