[自学考试] [02142数据结构导论] Part2 线性结构

Part1 概论
Part2 线性结构
Part3 树形结构
Part4 图形结构
Part5 查找
Part6 排序


线性表、栈(后进先出)、队列(先进先出)、数组

线性表的顺序存储

1.类型定义
2.算法实现
(1)插入
(2)删除
(3)定位
3.算法分析

线性表的链接存储

单链表

1.类型定义

//假设数据元素的类型为DataType,单链表的类型定义如下:
typedef struct node
{
    DataType data;
    struct node *next;
}Node,*LinkList;

2.初始化
3.求表长
4.读表元素
5.定位

//在带头结点的单链表上实现的算法为:
int LocateLinkList(LinkList head,DataType x)
//求链表中值为x的结点的序号,如不存在,返回0
{
    Node *p;    //p是工作指针
    p=head->next;   //初始值p指向首结点
    int i=0;    //i代表节点的序号,这里置初值为0
    while((p!=NULL)&&(p->data!=x)) //访问链表
    {
        i++;
        p=p->next;  //p移至下一个结点
    }
    if(p!=NULL)  return i+1;
    else  return 0;
}

6.查找

//在带头结点的单链表上实现的算法为:
Node * GetLinkList(LinkList head,int i)
//在单链表中寻找第i个结点元素,返回指向该结点的指针,否则返回NULL
{
    Node *p;    //p是工作指针
    p=head->next;   //初始值p指向首结点
    int cnt=1;
    while((p!=NULL) && (cnt<i))   //当未找到第i个结点且未到尾结点时,继续后移
    {
        cnt++;
        p=p->next;
    }
    if(i==cnt)  return p;  //找到第i个结点    
    else    return NULL;
}

7.插入

//在带头结点的单链表上实现的算法为:
void InsertLinkList(LinkList head,DataType x,int i)
//在单链表中的第i个数据元素结点之前插入一个值为x的新结点
{
    Node *p,*q; //p为工作指针,q为新结点
    if(i==1)    p=head;
    else  p=GetLinkList(head,i-1);
    while(p!=NULL)
    {
        q=malloc(sizeof(Node)); //生成新结点
        q->data=x;
        q->next=p->next;    
        p->next=q;
    }
    else exit("找不到插入位置")
}

8.删除

//在带头结点的单链表上实现的算法为:
void DeleteLinkList(LinkList head,int i)
//删除链表中第i个结点
{
    Node *p,*r;   //p为待删结点的直接前驱,r为待删结点
    if(i==1)  p=head; 
    else    p=GetLinkList(head,i-1) //先找到待删结点的直接前驱
    if((p!=NULL)&&(p->next!=NULL)) //若待删结点且直接前驱都存在
    {
        r=p->next;      //r指向待删结点
        p->next=r->next;    //移出待删结点
        free(r);    //释放已移出结点r的空间
    }
    else    exit("找不到要删除的结点");      //结点不存在
}

9.建表

  • 头插法
  • 尾插法

10.删除重复结点

循环链表

单项循环链表
双向循环链表

1.类型定义
2.初始化
3.求表长
4.定位
5.插入
6.删除


栈的顺序实现

1.顺序栈的类型定义

const int maxsize=6;    //顺序栈的容量
typedef struct seqstack
{
    DataType data[maxsize]; //存储栈中数据元素的数组
    int top;    //标志栈顶位置的变量
}SeqStk;

2.初始化

    int InitStack(SeqStk *stk)
{
    stk->top=0;
    return 1;
}

3.判栈空

int EmptyStack(SeqStk *stk)
//若栈为空,返回1,否则返回0
{
    if(stk->top==0) return 1;
    else return 0;
}

4.进栈

int Push(SeqStk *stk,DataType x)
//若栈未满,可进栈,否则提示出错
{
    if(stk->top=maxsize-1)
    {
        error("栈已满");
        return 0;
    }
    else{
        stk->top++;     //top值加1
        stk->data[stk->top]=x;  //元素进栈
        return 1;
    }
}

5.出栈

int Pop(SeqStk *stk)
{
    if(EmptyStack(stk))
    {
        error("下溢");
        return 0;
    }
    else
    {   
        stk->top--;     //top值减1
    }
}

6.取栈顶元素

DataType GetTop(SeqStk *stk)
{
    if(EmptyStack(stk))     //栈空
        return NULLData;
    else
        return stk->data[stk->top];     //返回栈顶数据元素
}

7.双栈⭐⭐

栈的链式实现

1.链栈的类型定义

typedef struct node
{
    DataType data;
    struct node *next;
}Lkstk;

2.初始化

void InitStack(LkStk *LS)
{
    LS=(LkStk *)malloc(sizeof(LkStk));
    LS->next=NULL;  //建立一个空栈
}

3.判栈空

int EmptyStack(LkStk *LS)
{
    if(Ls->next==null)  return 1;
    else return 0;
}

4.进栈

void Push(LkStk *LS,DataType x)
{
    LkStk *temp;
    temp=(LkStk *)malloc(sizeof(LkStk));
    temp->data=x;
    temp->next=LS->next;
    LS->next=temp;
}

5.出栈

int Pop(LkStk *LS)
{
    if(!EmptyStack(LS))
    {
        LkStk *temp;
        temp=LS->next;
        Ls->next=temp->next;
        free(temp);
        return 1;
    }
    else  return 0;
}

6.获取栈顶元素

DataType GetTop(LkStk *LS)
{
    if(!EmptyStack(LS)) return LS->next->data;
    else    return NULLData;
}

7.链表逆置

LkStk * reverseList(LkStk *head)
{
    LkStk *p,*q;
    p=head->next;   //p指向原链表首结点
    head->next=null;    //逆置链表初始为空
    while(p!=NULL)  //遍历原链表,直至为空
    {
        q=p;    //q指向原链表的首结点
        p=p->next;  //p指向原链表的下一个结点
        
        q->next=head->next; 
        head->next=q;       //“头插”到逆置链表中,q成为逆置链表的“新”的第一个结点
    }
    return head;
}

队列的顺序实现

1.循环队列的类型定义

typedef struct cycqueue
{
    DataType data[maxsize];
    int front,rear;
}CycQue;
CycQue CQ;

2.初始化

void InitQueue(CycQue CQ)
{
    CQ.front=0;
    CQ.rear=0;
}

3.判队列空

int EmptyQueue(CycQue CQ)
{
    if(CQ.front==CQ.rear)
        return 1; //队列为空,返回1
    else
        return 0; //队列不为空,返回0

}

4.入队列

int EnQueue(CycQue CQ, DataType x)
{
    if((CQ.rear+1)%maxsize==CQ.front)
    {
        error("队列满");
        return 0;
    }
    else
    {
        CQ.rear=(CQ.rear+1)%maxsize;
        CQ.data[CQ.rear]=x;
        return 1;
    }
}

5.出队列

int OutQueue(CycQue CQ)
{
    if(EmptyQueue(CQ))
    {
        error("队列空");
        return 0;
    }
    else
    {
        CQ.front=(CQ.front+1)%maxsize;
        return 1;
    }
}

6.取队列首元素

DataType GetHead(CycQue CQ)
{
    if(EmptyQueue(CQ))
        return NULLData;
    else
        return CQ.data[(CQ.front+1)%maxsize];
}

队列的链式存储

1.链接队列的类型定义

typedef struct LinkQueueNode
{
    DataType data;
    struct LinkQueueNode *next;
}LkQueNode;
typedef struct LkQueue
{
    LkQueNode *front,*rear;
}LkQue;
LkQue LQ;

2.初始化

void InitQueue(LkQue *LQ)
{
    LkQueNode *temp;
    temp=(LkQueNode *)malloc(sizeof(LkQueNode));
    LQ->front=temp;
    LQ->rear=temp;
    (LQ->front)->next=NULL;
}

3.判队列空

int EmptyQueue(LkQue LQ)
{
    if(LQ.rear==LQ.front)
        return 1;
    else return 0;
}

4.入队列

//入链接队列就是新建一个新的结点,把新的结点放在尾结点后插入
void EnQueue(LkQueue *LQ, DataType x)
{
    LkQueNode *temp;    
    temp=(LkQueNode *)malloc(sizeof(LkQueNode));
    temp->data=x;
    temp->next=NULL;
    
    (LQ->rear)->next=temp;  //新结点入队列
    LQ->rear=temp;  //置新的队列尾结点
}

5.出队列

int OutQueue(LkQue *LQ)
{
    if(EmptyQueue(LQ))
    {
        error("队列空");
        return 0;
    }
    else
    {
        LinkQueueNode *temp;
        temp=(LQ->front)->next; //temp指向首结点
        
        (LQ->front)->next=temp->next; //修改头结点的指针域指向新的首结点
        if(temp->next)
            LQ->rear=LQ->front; //无首结点时,front和rear都指向头结点
        free(temp);
        return 1;
    }
}

6.取队列首元素

DataType GetHead(LkQue LQ)
{
    if(EmptyQueue(LQ))
    {
        error("队列空");
        return NULLData;
    }
    else
    {
        LinkQueueNode *temp;
        temp=(LQ.front)->next;
        return temp->data;
    }
}

矩阵的压缩存储⭐⭐

转载于:https://www.cnblogs.com/Sukie-s-home/articles/11512058.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值