线性表及其C语言实现

2.1线性表

2.1.1什么是线性表?

线性表(Linear List):由同类型数据元素构成有序序列的线性结构。

特点:1.表中元素个数称为线性表的长度;

         2.线性表没有元素时称为空表;

3.表的起始位置称为表头,表的结束位置称为表尾。

2.1.2线性表的抽象数据类型描述

类型名称:线性表(List)

数据对象集:线性表是n(n>=0)个元素构成的有序序列(a1,a2,a3,…an)

操作集:

1.初始化一个空线性表

2.根据位序k返回相应元素

3.在线性表中查找对象第一次出现的位置

4.在位序i前插入一个新元素x

5.删除指定位序的元素

6.返回线性表的长度

2.1.3线性表的顺序存储实现

很简单,如对象数组。

2.1.4线性表的链式存储实现
#include <stdio.h> 
#include <stdlib.h>
#include <string.h>

/*链表中元素的结构体定义,以下只是一个例子*/
typedef struct student{
    char num[20];       //学号
    char name[20];    //姓名
    char sex[5];    //性别
    int age;          //年龄
} ElementType;

/*链表的定义*/ 
typedef struct LNode * List; //链表结点的指针 
struct LNode {               //链表的结点 
    ElementType Data;
    List Next;
};

struct LNode L; //链表 
List PtrL; //链表的头指针 

/*操作集的声明*/
int Length(List PtrL); //返回链表长度 
List FindKth(int K, List PtrL); //按序号查找 
List Find(ElementType X, List PtrL); //按值查找 
List Insert(ElementType X, int i, List PtrL); //在序号i处插入 
List Delete(int i, List PtrL); //删除序号i处的元素 
List initialize(); //初始化一个头结点

int Length(List PtrL) {
    List P = PtrL; // p指向表的第一个结点 
    int j = 0;
    while (P) {
        P = P->Next;
        j++; //当前p指向第j个结点 
    }
    return j;
} 

List FindKth(int K, List PtrL) {
    List P = PtrL; // p指向表的第一个结点
    int i = 1;
    while (P != NULL && i < K) {
        P = P->Next;
        i++;
    } 
    if (i == K) return P; //找到返回p的指针 
    else return NULL; //找不到返回空 
} 

List Find(ElementType X, List PtrL) {
    List P = PtrL; // p指向表的第一个结点
    while (P != NULL) {
        if (strcmp(P->Data.num, X.num) == 0 &&
            strcmp(P->Data.name, X.name) == 0 &&
            strcmp(P->Data.sex, X.sex) == 0 &&
            P->Data.age == X.age) {
            return P;
        }
        P = P->Next;
    }
    return NULL;
} 

List Insert(ElementType X, int i, List PtrL) {
    List P, S;
    if (i == 1) { // i==1是在表头插入 
        S = (List)malloc(sizeof(struct LNode));
        S->Data = X;
        S->Next = PtrL;
        return S; //直接返回表头 
    } 
    P = FindKth(i-1, PtrL); //查找第i-1个结点
    if (P == NULL) {
        printf("parameter error!");
        return NULL;
    } else {
        S = (List)malloc(sizeof(struct LNode));
        S->Data = X; //装载元素 
        S->Next = P->Next; //将结点插入在 i-1 ~ i 之间 
        P->Next = S;
        return PtrL;
    }
}

List Delete(int i, List PtrL) {
    List P, S;
    if (i == 1) { //要删除的结点是第一个结点            
        S = PtrL;
        if (PtrL != NULL) PtrL = PtrL->Next; 
        else return NULL;
        free(S);
        return PtrL;
    } 

    P = FindKth(i-1, PtrL); //查找第i-1个结点
    if (P == NULL) {
        printf("第%d个结点不存在", i-1);
        return NULL;
    } else if (P->Next == NULL) {
        printf("第%d个结点不存在", i);
        return NULL;
    } else {
        S = P->Next; // S指向要删除的结点 
        P->Next = S->Next; //将i-1结点的键连接上i的下一个结点 
        free(S);
        return PtrL;
    }
} 

List initialize() { //初始化一个头结点默认值为0 
    ElementType defau = {
        .num = "123456789",       //学号
        .name = "lihua",  //姓名
        .sex = "man",     //性别
        .age = 18         //年龄
    };
    List list = (List)malloc(sizeof(struct LNode));
    list->Data = defau;
    list->Next = NULL;
    return list;
}

int main() {
    // 测试代码可以放在这里
    PtrL = initialize();
    printf("Initialized list with head: %s, %s, %s, %d\n", PtrL->Data.num, PtrL->Data.name, PtrL->Data.sex, PtrL->Data.age);

    ElementType newStudent = {
        .num = "2",
        .name = "zhangsan",
        .sex = "male",
        .age = 20
    };

    PtrL = Insert(newStudent, 2, PtrL);
    printf("Length of list: %d\n", Length(PtrL));

    List found = Find(newStudent, PtrL);
    if (found) {
        printf("Found student: %s, %s, %s, %d\n", found->Data.num, found->Data.name, found->Data.sex, found->Data.age);
    } else {
        printf("Student not found.\n");
    }

    PtrL = Delete(1, PtrL);
    printf("Length of list after deletion: %d\n", Length(PtrL));

    return 0;
}

 

2.1.5广义表

广义表(Deneralized List)

是线性表的推广;

对于线性表而言,n个元素都是基本的单元素;

在广义表中,这些元素不仅可以是单元素也可以是另一个广义表。

2.1.6多重链表(广义表的实现)

链表中的节点可能同时隶属于多个链表。

多重链表中节点的指针域会有多个,如其中包含了next与sublist两个指针域。

但是包含了两个指针域的链表并不一定是多重链表,比如双向链表就不是多重链表。

且:多重链表有个泛的用途就是,诸如图,树这样相对复杂的数据结构都可以采用多重链表方式来实现存储。

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值