数据结构和算法:Big-Data-Structure 大话数据结构 算法复杂度 线性表 非线性表 查找 排序_大话数据结构矩阵代码(2)

// 相关操作状态定义
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int  Status;            // Status 是函数的类型,其值是函数结果状态码,如 OK 等

/\*\*
 获取线性表中第 i 个元素
 
 @param L 线性表 L, 必须已存在
 @param i 要获取的编号, 需满足 i ≤ i ≤ ListLength(L)
 @param e 对应元素返回
 @return 操作结果 OK/ERROR
 \*/
Status GetSqListElem(SqList L, int i, ElemType \*e) {
    if (L.length==0 || i<1 || i>L.length) return ERROR;
    \*e = L.data[i-1];
    return OK;
}


插入操作
/\*\*
 向线性表的第 i 个位置插入元素
 
 @param L 线性表, 必须存在
 @param i 位置编号, 需满足 i ≤ i ≤ ListLength(L)
 @param e 要插入的元素
 @return 操作结果 OK/ERROR
 \*/
Status SqListInsert(SqList \*L, int i, ElemType e) {
    
    // 1. 顺序线性表已满
    if (L->length == MAXSIZE) return ERROR;
    // 2. 插入位置i 不在线性表范围内
    if (i<1 || i>L->length+1) return ERROR;
    // 插入数据位置不在表尾部
    if (i <= L->length) {
        // 3.将要插入位置后的元素统一后移一位
        for (int k=L->length-1; k>=i-1; k--) {
            L->data[k+1] = L->data[k];
        }
    }
    // 4.将要插入的元素 填入 第i个位置
    L->data[i-1] = e;
    // 5. 表长+1
    L->length ++;

    return OK;
}

删除操作
/\*\*
 删除线性表第 i 个位置的元素
 
 @param L 线性表, 必须存在
 @param i 要删除的位置编号, 需满足 i ≤ i ≤ ListLength(L)
 @param e 被删除的元素返回
 @return 操作结果 OK/ERROR
 \*/
Status SqListDelete(SqList \*L, int i, ElemType \*e) {
    
    // 1. 空表
    if (L->length==0) return ERROR;
    // 2. 要删除的位置不正确
    if (i<1 || i>L->length) return ERROR;
    \*e = L->data[i-1];
    // 3. 若删除的不是表尾, 将删除位置 后继元素 前移
    if (i<L->length) {
        for (int k=i; k<L->length; k++) {
            L->data[k-1] = L->data[k]; // 依次前移
        }
    }
    // 4. 表长-1
    L->length --;
    
    return OK;
}

线性表的链式存储结构

线性表链式存储结构的定义

为了表示每个数据元素 ai 与其直接后继元素 ai+1 之间的逻辑关系,对数据元素 ai 来说,出了存储其本身的信息之外,还需存储一个指示其直接后继的信息(即直接后继的存储位置)。把存储数据元素信息的域称为数据域,把存储直接后继位置的域称为指针域。指针域中存储的信息乘坐指针或链。这两部分信息组成数据元素 ai 的存储映像,称为结点(Node)。

n 个节点(ai的存储映像)链接成一个链表,即为线性表 (a1, a2, …, an) 的连式存储结构,因为此链表的每个节点中只包含一个指针域,所以叫做单链表

链表中第一个节点的存储位置叫做头指针

有时,为了更加方便的对链表进行操作,会在单链表的第一个结点前附设一个结点,称为头结点

头指针和头结点的异同

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

线性表链式存储结构代码描述
/\*\*
 线性表的单链表的存储结构
 
 结点由存放数据元素的数据域和存放后继结点地址的指针域组成
 \*/
typedef struct Node {
    ElemType data;     // 数据信息
    struct Node \*next; // 指向信息/单线联系
} Node;

// 定义 LinkList
typedef struct Node \*LinkList;

单链表的读取

/\*\*
 获取单链表第i 个位置的元素
 
 @param L 单链表, 必须存在
 @param i 要获取元素的位置标号 1 ≤ i ≤ ListLength(L)
 @param e 返回元素
 @return 操作是否成功 OK/ERROR
 \*/
Status GetLinkListElem(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;
}

单链表的插入与删除

单链表的插入
/\*\*
 向单链表第 i 个位置插入元素
 
 @param L 单链表, 必须存在
 @param i 要插入的位置标号, 1 ≤ i ≤ ListLength(L)
 @param e 要插入的元素
 @return 操作结果 OK/ERROR
 \*/
Status LinkListInsert(LinkList \*L, int i, ElemType e) {
    
    LinkList p = \*L;
    int j = 1;
    
    while (p && j<i) {
        p = p->next;
        ++j;
    }
    // 第 i 个元素不存在
    if (!p || j >i) return ERROR;
    
    // 生成一个新节点
    LinkList s = (LinkList)malloc(sizeof(Node));
    
    // 插入元素
    s->data = e;
    s->next = p->next;
    p->next = s;
    return OK;
}

单链表的删除
/\*\*
 移除单链表的第 i 个位置的元素
 
 @param L 单链表,必须存在
 @param i 要移除元素的位置标号, 1 ≤ i ≤ ListLength(L)
 @param e 要删除的元素返回
 @return 操作结果 OK/ERROR
 \*/
Status LinkListDelete(LinkList \*L, int i, ElemType \*e) {
    
    LinkList p = \*L;
    int j = 1;
    while (p && j < i) {
        p = p->next;
        ++j;
    }
    // 第 i 个节点不存在
    if (!p->next || j > i) return ERROR;
    
    LinkList q = p->next;
    p->next = q->next;
    \*e = q->data;
    free(q);
    
    return OK;
}

单链表的整表创建

头插法

/\*\*
 随机产生 n 个元素的值, 建立带表头节点的单链线性表 L(头插法)
 
 @param L 创建的线性表 L 返回
 @param n 表元素个数
 @return 操作结果 OK/ERROR
 \*/
Status CreateLinkListHead(LinkList \*L, int n) {
    
    srand((unsigned int)time(0));
    \*L = (LinkList)malloc(sizeof(Node));
    (\*L) -> next = NULL;
    for (int i=0; i<n; i++) {
        LinkList p = (LinkList)malloc(sizeof(Node));
        p->data = rand() % 100 + 1;
        p->next = (\*L)->next;
        (\*L)->next = p;
    }
    return OK;
}

尾插法

/\*\*
 随机产生 n 个元素的值, 建立带表头节点的单链线性表 L(尾插法)
 
 @param L 创建的线性表 L 返回
 @param n 表元素个数
 @return 操作结果 OK/ERROR
 \*/
Status CreateLinkListTail(LinkList \*L, int n) {
    
    srand((unsigned int)time(0));
    (\*L) = (LinkList)malloc(sizeof(Node));
    LinkList r = \*L;
    
    for (int i=0; i<n; i++) {
        LinkList p = (Node \*)malloc(sizeof(Node));
        p->data = rand()%100+1;
        r->next = p;
        r = p;
    }
    r->next = NULL;
    return OK;
}


单链表的整表删除

  • 18
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值