2.1 动态单链表

全书链接: 408笔记——数据结构(C语言版)(将书上例题用C语言列出来,可以直接在IDE(Xcode)上运行)

2.1 动态单链表

单链表:每个结点只包含一个指针域的链表

main.c
#include <stdio.h>
#include <stdlib.h>
//#include "sequentialStorage.h"
#include "linkStorage.h"



int main(int argc, const char * argv[]) {
    // insert code here...
    printf("Hello, World!\n");
//    sequentialStorageTest();
    
    linkStorageTest();
    
    
    return 0;
}
common.h(common.c是空的)
#ifndef common_h
#define common_h

#include <stdio.h>
#include <stdlib.h>

typedef int ElemType;
typedef int Status;

#endif /* common_h */
linkStorage.h
//
//  linkStorage.h
//  Ctest
//
//  Created by macvivi on 2019/10/30.
//  Copyright © 2019 macvivi. All rights reserved.
//

//链式存储(链式线性表)
#ifndef linkStorage_h
#define linkStorage_h

#include <stdio.h>
#include"common.h"

//28页
typedef struct LNode{
    ElemType data;
    struct LNode *next;
} LNode, LinkList;

//链式线性表测试代码
void linkStorageTest(void);

//遍历链表
void bianliLS(LinkList *L);

//建立一个带头结点的单链表   30页  算法2.10
LinkList * CreateList_L(int n);

//获取链表中第i个元素的值   29页
ElemType GetElem_L(LinkList *L,int i);

//在单链表L中第i个位置之前插入元素e  29页  算法2.8
Status ListInsert_L(LinkList *L, int i, ElemType e);

//在带头结点的单联表L中,删除第i个元素,并返回其值   30页  算法2.9
ElemType ListDelete_L(LinkList *L, int i);

//合并单链表  31页 算法2.11  以算法2.1为例
LinkList *MergeList_L(LinkList *La,LinkList *Lb);




#endif /* linkStorage_h */

linkStorage.c
//
//  linkStorage.c
//  Ctest
//
//  Created by macvivi on 2019/10/30.
//  Copyright © 2019 macvivi. All rights reserved.
//

#include "linkStorage.h"

void linkStorageTest(void){
    
    LinkList *L= CreateList_L(3);
    bianliLS(L);

    ElemType e = GetElem_L(L, 2);
    printf("%d\n",e);
    printf("--------\n");

    ListInsert_L(L, 3, 9);
    bianliLS(L);

    ElemType a = ListDelete_L(L, 4);
    printf("%d\n",a);
    printf("---------------\n");
    bianliLS(L);
    
    printf("两个单链表的合并\n");
    LinkList *La = CreateList_L(0);
    ListInsert_L(La, 1, 3);
    ListInsert_L(La, 2, 5);
    ListInsert_L(La, 3, 8);
    ListInsert_L(La, 4, 11);
    bianliLS(La);
    
    LinkList *Lb = CreateList_L(0);
    ListInsert_L(Lb, 1, 2);
    ListInsert_L(Lb, 2, 6);
    ListInsert_L(Lb, 3, 8);
    ListInsert_L(Lb, 4, 9);
    ListInsert_L(Lb, 5, 11);
    ListInsert_L(Lb, 6, 15);
    ListInsert_L(Lb, 7, 20);
    bianliLS(Lb);
    
    LinkList *Lc = MergeList_L(La, Lb);
    bianliLS(Lc);
    
   
    
}

LinkList *MergeList_L(LinkList *La,LinkList *Lb){
    //已知单链线性表La和Lb的元素按值非递减排列
    //归并La和Lb得到新的单链线性表Lc,Lc的元素也按值非递减排列
    LinkList *pa = La->next;
    LinkList *pb = Lb->next;
    LinkList *pc = La;  //用La的头结点作为Lc的头结点
    while (pa && pb) {
        if (pa->data <= pb->data) {
            pc->next = pa;
            pc = pa;
            pa = pa->next;
        } else {
            pc->next = pb;
            pc = pb;
            pb = pb->next;
        }
    }
    pc->next = pa?pa:pb;  //插入剩余段
    free(Lb);   //释放Lb的头结点
    return La;
}


ElemType ListDelete_L(LinkList *L, int i){
    LinkList *p = L;
    int j = 0;
    while (p->next && j < i-1) {
        p = p->next;//寻找第i个结点,并令p指向其前趋
        j++;
    }
    if (!(p->next) || j > i-1) {
        return 0;
    }
    //删除并释放结点
    LinkList *q = p->next;
    p->next = q->next;
    ElemType e = q->data;
    free(q);
    
    return e;
}


Status ListInsert_L(LinkList *L, int i, ElemType e){
    LinkList *p = L;
    int j = 0;
    while (p && j < i-1) {
        p = p->next;  //寻找第i-1个节点
        j++;
    }
    if (!p || j > i-1) {
        return 0;
    }
    LinkList *s = (LinkList*)malloc(sizeof(LNode));
    s->data = e;
    s->next = p->next;
    p->next = s;
    return 1;
    
    return 0;
}


ElemType GetElem_L(LinkList *L,int i){
    //L为带头结点的单链表的头指针
    //当第i个元素存在时,将其返回
    LinkList *p = L->next;
    int j = 1;
    while (p && j<i) {
        p = p->next;
        j++;
    }
    if (!p || j>i) {
        return 0;  //第i个元素不存在
    }
    
    return p->data;
}


void bianliLS(LinkList *L){
    LinkList *p = L;
    while (p->next) {
        p = p->next;
        printf("%d\n",p->data);
    }
    printf("---------\n");
}

LinkList* CreateList_L(int n){
    //逆位序输入n个元素的值,建立带表头结点的单链线性表L。
   LinkList* L = (LinkList*)malloc(sizeof(LNode));
    L->next = NULL;   //先建立一个带头结点的单链表
    for (int i=n; i > 0; i--) {
        LinkList *p = (LinkList *)malloc(sizeof(LNode));  //生成新节点
//        scanf("%d",&p->data);
        p->data = i+100;
        p->next = L->next;
        L->next = p;
       
    }
    return L;
}

打印结果:
Hello, World!
101
102
103
---------
102
--------
101
102
9
103
---------
103
---------------
101
102
9
---------
两个单链表的合并
3
5
8
11
---------
2
6
8
9
11
15
20
---------
2
3
5
6
8
8
9
11
11
15
20
---------
Program ended with exit code: 0
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值