数据结构实验1— 线性表、链表的实现

实现顺序表各种基本操作

实验要求

编写程序实现顺序表的各种基本运算,并在此基础上设计一个主程序完成如下功能:

(1)初始化顺序表L;
(2)依次在L尾部插入元素-1,21,13,24,8;
(3)输出顺序表L;
(4)输出顺序表L长度;
(5)判断顺序表L是否为空;
(6)输出顺序表L的第3个元素;
(7)输出元素24的位置;
(8)在L的第4个元素前插入元素0;
(9)输出顺序表L;
(10)删除L的第5个元素;
(11)输出顺序表L。

程序代码

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
#define LIST_INIT_SIZE 100
#define LISTINCREMENT 10
typedef int ElemType;
typedef int Status;
typedef int Boolean;
const int l = 40;
typedef struct{
    ElemType * elem;
    int length;
    int listsize;
}SqList,*pSqList;

Status compare(ElemType a, ElemType b)
{
    if(a<b) return TRUE;
    else return FALSE;
}
Status InitList_Sq(pSqList L)
{
    L->elem = (ElemType *) malloc(LIST_INIT_SIZE *sizeof(ElemType));
    if(!L->elem) exit(OVERFLOW);
    L->length = 0;
    L->listsize = LIST_INIT_SIZE;
    return OK;
}
Status ListInsert_Sq(pSqList L, int i, ElemType e)
{
    if(i<1 || i>L->length+1) return ERROR;
    if(L->length >= L->listsize){
        ElemType * newbase = (ElemType *) realloc(L->elem,(L->listsize+LISTINCREMENT) * sizeof(ElemType));
        if(!newbase) exit(OVERFLOW);
        L->elem = newbase;
        L->listsize +=LISTINCREMENT;
    }
    ElemType * q = &(L->elem[i-1]);
    for(ElemType * p = &(L->elem[L->length-1]);p>=q;--p) *(p+1) = *p;
    *q = e;
    ++L->length;
    return OK;
}
Status ListDelete_Sq(pSqList L, int i, ElemType * e)
{
    if((i<1) || (i> L->length)) return ERROR;
    ElemType * p = &(L->elem[i-1]);
    *e = *p;
    ElemType *q = L->elem + L->length - 1;
    for(++p; p<=q; ++p) *(p-1) = *p;
    --L->length;
    return OK;
}
Status LocateElem_Sq(pSqList L, ElemType e)
{
    int i = 1;
    ElemType * p = L->elem;
    while(i<= L->length && *p++ != e)++i;
    if(i<=L->length) return i;
    else return 0;
}
Status ListTreverse_Sq( pSqList L)
{
    ElemType * p = L->elem;
    ElemType * q = L->elem + L->length -1;
    bool first = true;
    for(;p<=q;++p){
        if(first){printf("%d",*p); first = false;}
        else printf(" %d",*p);
    }
    printf("\n");
    return OK;
}
Status ListIsEmpty_Sq(pSqList L)
{
    if(L->length == 0) return TRUE;
    else return FALSE;
}
Status ListLocatePrint_Sq(pSqList L, int i)
{
    if(i<1 || i>=L->length+1) return ERROR;
    else
        printf("The %d number is %d\n",i,*(L->elem+(i-1)));
    return OK;
}
Status Paint()
{
    printf("|"); printf("     The Experiment Of LinkList      ") ;printf("|\n");
    printf("|"); printf("        Sequential LinkList          ") ;printf("|\n");
    printf("|"); printf("        Author: Luo Peng Fei         ") ;printf("|\n");
    printf("|"); printf("           Date:2017/3/29            ") ;printf("|\n");
    return OK;
}
int main()
{
    Paint();
    SqList L;
    InitList_Sq(&L);
    int n,pos,temp;
    printf("|"); printf("         请输入数字的数量            ") ;printf("|\n");
    scanf("%d",&n);
    printf("|"); printf("        请依次输入%d个数字            ",n) ;printf("|\n");
    for(int i = 0; i<n; ++i){
        int t; scanf("%d",&t);
        ListInsert_Sq(&L,L.length+1,t);
    }
    printf("|"); printf("         当前链表的内容是            ") ;printf("|\n");
    ListTreverse_Sq(&L);
    printf("当前链表%s\n",ListIsEmpty_Sq(&L)?"空":"不空");
    printf("|"); printf("         当前链表的长度是%d           ",L.length) ;printf("|\n");
    printf("|"); printf("   您想查询当前链表哪个位置的元素    ") ;printf("|\n");
    scanf("%d",&n);
    if(!ListLocatePrint_Sq(&L,n)) printf("抱歉位置错误\n");
    printf("|"); printf("    请输入您想要查询位置的元素值     ") ;printf("|\n");
    scanf("%d",&n);
    pos = LocateElem_Sq(&L,n);
    printf("|"); printf("         %d在链表中的位置是%d          ",n,pos) ;printf("|\n");
    printf("|"); printf("    请分别输入要插入元素的值和位置     ") ;printf("|\n");
    scanf("%d%d",&pos,&n);
    ListInsert_Sq(&L,pos,n);
    printf("|"); printf("         当前链表的内容是            ") ;printf("|\n");
    ListTreverse_Sq(&L);
    printf("|"); printf("       请输入删除元素的位置          ") ;printf("|\n");
    scanf("%d",&n);
    if(!ListDelete_Sq(&L,n,&temp)) printf("抱歉位置错误!\n");
    printf("|"); printf("         当前链表的内容是            ") ;printf("|\n");
    ListTreverse_Sq(&L);
    return 0;
}

运行结果

这里写图片描述

实现单链表各种基本操作

实验要求

编写程序实现单链表的各种基本运算,并在此基础上设计一个主程序完成如下功能:
(1)初始化单链表h;
(2)依次采用头插法插入元素-1,21,13,24,8;
(3)输出单链表h;
(4)输出单链表h长度;
(5)判断单链表h是否为空;
(6)输出单链表h的第3个元素;
(7)输出元素24的位置;
(8)在h的第4个元素前插入元素0;
(9)输出单链表h;
(10)删除h的第5个元素;
(11)输出单链表h。

程序代码

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
#define LIST_INIT_SIZE 100
#define LISTINCREMENT 10
typedef int ElemType;
typedef int Status;
typedef int Boolean;
typedef struct LNode{
    ElemType data;
    struct LNode * next;
}LNode, *LinkList;
const int l = 40;
Status ListIsEmpty_L(LinkList L)
{
    if(L->next == NULL) return FALSE;
    else return TRUE;
}
Status GetElem_L(LinkList L, int i, ElemType *e)
{
    LinkList p = L->next; int j = 1;
    while(p && j<i){
        p = p->next; ++j;
    }
    if(!p || j>i) return ERROR;
    *e = p->data;
    return OK;
}
Status ListInsert_L( LinkList  L, int i, ElemType e)
{
    LinkList p = L; int j = 0;
    while(p && j<i-1){
        p = p->next; ++j;
    }
    if(!p || j>i-1) return ERROR;
    LinkList s= (LinkList) malloc(sizeof(LNode));
    s->data = e;
    s->next = p->next;
    p->next = s;
    return OK;
}
Status ListDelete_L(LinkList  L, int i, ElemType * e)
{
    LinkList p = L; int j = 0;
    while(p->next && j< i-1){
        p = p->next; ++j;
    }
    if(!(p->next) || j>i-1) return ERROR;
    LinkList q = p->next;
    p->next = q->next;
    *e = q->data;
    free(q);
    return OK;
}
void CreatList_L(LinkList &L , int n)
{
    L = (LinkList) malloc(sizeof(LNode));
    L->next = NULL;
    for(int i = 0; i<n; ++i){
        LinkList p = (LinkList) malloc(sizeof(LNode));
        int t;
        scanf("%d",&t);
        p->data = t;
        p->next = L->next;
        L->next = p;
    }
}
Status ListTreverse_L(LinkList L)
{
    if(L->next == NULL) return ERROR;
    else{
        LinkList p = L->next;
        bool first = true;
        while(p){
            if(first){
                printf("%d",p->data);
                first = false;
            }else{
                printf(" %d",p->data);
            }
            p = p->next;
        }
        printf("\n");
    }
    return OK;
}
Status ListLenth(LinkList L,int * length )
{
    if(!L->next) *length = 0;
    else{
        LinkList p = L->next; int j = 0;
        while(p){
            j++;
            p = p->next;
        }
        * length = j;
    }
    return OK;
}
Status ListLocate(LinkList L, int n,int *e)
{
    if(!L->next) *e = 0;
    else{
        LinkList p = L->next;
        int j = 1;
        while(p->data != n){
            p = p->next;
            ++j;
        }
        int lenth  = ListLenth(L,&lenth);
        if(j>=lenth && !p) return ERROR;
        *e = j;
    }
    return OK;
}
Status Paint()
{
    printf("|"); printf("     The Experiment Of LinkList      ") ;printf("|\n");
    printf("|"); printf("         Pointer   LinkList          ") ;printf("|\n");
    printf("|"); printf("        Author: Luo Peng Fei         ") ;printf("|\n");
    printf("|"); printf("           Date:2017/3/29            ") ;printf("|\n");
    return OK;
}
int main()
{
    Paint();
    LinkList L = NULL ;
    int n,length,temp,pos;
    printf("|"); printf("         请输入数字的数量            ") ;printf("|\n");
scanf("%d",&n);
printf("|"); printf("        请依次输入%d个数字            ",n) ;printf("|\n");
    CreatList_L(L,n);
    printf("|"); printf("         当前链表的内容是            ") ;printf("|\n");
    ListTreverse_L(L);
    printf("当前链表%s\n",ListIsEmpty_L(L)?"不空":"空");
    ListLenth(L,&length);
    printf("|"); printf("         当前链表的长度是%d           ",length) ;printf("|\n");
    printf("|"); printf("   您想查询当前链表哪个位置的元素    ") ;printf("|\n");
    scanf("%d",&n);
    if(!GetElem_L(L,n,&temp)) printf("抱歉位置错误\n");
    else {printf("|"); printf("         %d在链表中的位置是%d          ",temp,n) ;printf("|\n");}
    printf("|"); printf("    请输入您想要查询位置的元素值     ") ;printf("|\n");
    scanf("%d",&n);
    if(!ListLocate(L,n,&pos)) printf("抱歉位置错误\n");
    else {printf("|"); printf("         %d在链表中的位置是%d          ",n,pos) ;printf("|\n");}
    printf("|"); printf("   请分别输入要插入元素的值和位置     ") ;printf("|\n");
    scanf("%d%d",&n,&pos);
    ListInsert_L(L,pos,n);
    printf("|"); printf("         当前链表的内容是            ") ;printf("|\n");
    ListTreverse_L(L);
    printf("|"); printf("       请输入删除元素的位置          ") ;printf("|\n");
    scanf("%d",&temp);
    if(!ListDelete_L(L,5,&temp)) printf("抱歉位置错误\n");
    printf("|"); printf("         当前链表的内容是            ") ;printf("|\n");
    ListTreverse_L(L);
    return 0;
}

运行结果

这里写图片描述

约瑟夫环问题

实验要求

问题描述

编号为1,2,…,n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。一开始任选一个正整数作为报数上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数。报m的人出列,将他的密码作为新的m值,从他在顺时针方向上的下一个人开始重新从1报数,如此下去,直至所有人全部出列为止。试设计一个程序求出出列顺序。

基本要求

选择单向循环链表作为存储结构模拟整个进程,按照出列的顺序输出各人的编号。

测试数据

m的初值为20;n=7,7个人的密码依次为:3,1,7,2,4,8,4。

程序代码

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
#define LIST_INIT_SIZE 100
#define LISTINCREMENT 10
typedef int ElemType;
typedef int Status;
typedef int Boolean;
typedef struct LNode{
    ElemType data;
    struct LNode * next;
}LNode, *LinkList;
int code[1000] = {};
LinkList head;
Status ListIsEmpty_L(LinkList L)
{
    if(L->next == NULL) return FALSE;
    else return TRUE;
}
Status GetElem_L(LinkList L, int i, ElemType *e)
{
    LinkList p = L->next; int j = 1;
    while(p && j<i){
        p = p->next; ++j;
    }
    if(!p || j>i) return ERROR;
    *e = p->data;
    return OK;
}
Status ListInsert_L( LinkList  L, int i, ElemType e)
{
    LinkList p = L; int j = 0;
    while(p && j<i-1){
        p = p->next; ++j;
    }
    if(!p || j>i-1) return ERROR;
    LinkList s= (LinkList) malloc(sizeof(LNode));
    s->data = e;
    s->next = p->next;
    p->next = s;
    return OK;
}
Status ListDelete_L(LinkList  L, int i, ElemType * e)
{
    LinkList p = L; int j = 0;
    while(p->next && j< i-1){
        p = p->next; ++j;
    }
    if(!(p->next) || j>i-1) return ERROR;
    LinkList q = p->next;
    p->next = q->next;
    *e = q->data;
    free(q);
    return OK;
}
void CreatList_L(LinkList &L , int n)
{
    L = (LinkList) malloc(sizeof(LNode));
    L->next = NULL;int num = n;
    for(int i = 0; i<n; ++i){
        LinkList p = (LinkList) malloc(sizeof(LNode));
        p->data = num--;
        p->next = L->next;
        L->next = p;
        if(!i) head = p;
    }
    head->next = L->next;
}
Status ListTreverse_L(LinkList L)
{
    if(L->next == NULL) return ERROR;
    else{
        LinkList p = L->next;
        bool first = true;
        while(p){
            if(first){
                printf("%d",p->data);
                first = false;
            }else{
                printf(" %d",p->data);
            }
            p = p->next;
        }
        printf("\n");
    }
    return OK;
}
Status ListLenth(LinkList L,int * length )
{
    if(!L->next) *length = 0;
    else{
        LinkList p = L->next; int j = 0;
        while(p){
            j++;
            p = p->next;
        }
        * length = j;
    }
    return OK;
}
Status ListLocate(LinkList L, int n,int *e)
{
    if(!L->next) *e = 0;
    else{
        LinkList p = L->next;
        int j = 1;
        while(p->data != n){
            p = p->next;
            ++j;
        }
        *e = j;
    }
    return OK;
}
Status Joseph(LinkList L,int n,int num)
{
    LinkList sta = L->next;
    LinkList ft;
    int cnt = 0 ; num = num-1;
    while(cnt != n){
        while(num--){
            ft = sta;
            sta = sta->next;
        }
        printf("%d ",sta->data);
        cnt++;
        num = code[sta->data-1];
        ft->next = sta->next;
    }
    return OK;
}
int main()
{
    LinkList L;
    int n,m;
    printf("请输入总共有几个人:\n");
    scanf("%d",&n);
    printf("请输入初始密码值:\n");
    scanf("%d",&m);
    printf("请依次输入1-%d号手中的密码值:\n",n);
    for(int i = 0; i<n;++i) scanf("%d",&code[i]);
    CreatList_L(L,n);
    printf("%d个人的出队顺序依次为:\n",n);
    Joseph(L,n,m);
    return 0;
}

运行结果

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值