C语言线性表-顺序存储结构学习笔记

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

/* 定义全局变量 */
#define MAXSIZE 100
#define OVERFLOW -2
#define OK 1
#define ERROR -1

/* 自定义类型 */      
typedef int Position;                                           // 线性表的最后一个成员(索引)类型
typedef int ElementType;                                        // 数据域索引 类型
// typedef struct LNode *PtrToLNode;                            // 定义结构类为 LNode 类型的指针
/* 定义节点 */
typedef struct LNode{
	ElementType Data[MAXSIZE];                                  // 数据域
	Position Last;                                              // 线性表的最后一个成员(索引)
} *PtrToLNode;
typedef PtrToLNode List;

/* 预定义函数 */
List InitList_Sq();                                             // 初始化
int listInsert(List L, int i, ElementType e);                   // 插入元素
int addList(List L, ElementType e);                             // 添加元素
void print(List L);                                             // 输出表 
int GetLength(List L);                                          // 表长度
int ListDalete_sq(List L, int i);                               // 删除元素       
int ClearList(List L);                                          // 置空
void DestroList (List L);                                       // 销毁
bool isEmpty(List L);                                           // 判断是否为空  
int GetElem(List L, int i, ElementType *e);                     // 查询与位置元素
int LocateElem(List L, ElementType e);                          // 对比元素并返回位置
int LocateElem2(List L, ElementType e);                         // 对比元素并返回位置
void mergeTable(List L1, List L2);                              // 合并线性表
List Orderly_merge_table(List LA, List LB, List LC);            // 有序表合并
/* 预定义函数end */

// 顺序增删改查
int main(int argc, char const *argv[])
{  
    int e, i, cx, LocateElemData, arr_length, arr_length2, arr_length3, arr_length4;

    // 初始化数组
    int arr[] = {7, 5, 3, 11};                                  // 表1
    int arr2[] = {2, 6, 3};                                     // 表2
    int arr3[] = {1, 7, 8};                                     // 表A
    int arr4[] = {2, 4, 6, 8, 10, 11};                          // 表B

    // 计算数组长度
    arr_length = sizeof(arr)/sizeof(int);                       // 表1 
    arr_length2 = sizeof(arr2)/sizeof(int);                     // 表2
    arr_length3 = sizeof(arr3)/sizeof(int);                     // 表A
    arr_length4 = sizeof(arr4)/sizeof(int);                     // 表B

    /* 初始化表 */
    printf("初始化表:\n");  
    List arrs = InitList_Sq(arrs);                              // 表1
    List arrs2 = InitList_Sq(arrs2);                            // 表2 
    List arrs3 = InitList_Sq(arrs3);                            // 表A
    List arrs4 = InitList_Sq(arrs4);                            // 表B 
    
    /* 添加表数据 */
    for (i = 0; i < arr_length; i++) addList(arrs, arr[i]);     // 表1
    print(arrs);    
    for (i = 0; i < arr_length2; i++) addList(arrs2, arr2[i]);  // 表2   
    print(arrs2);    
    for (i = 0; i < arr_length3; i++) addList(arrs3, arr3[i]);  // 表A
    print(arrs3);    
    for (i = 0; i < arr_length4; i++) addList(arrs4, arr4[i]);  // 表B  
    print(arrs4);

    /* 查询表是否为空 */
    printf("判断表是否为空:");
    isEmpty(arrs);

    /* 查询表长度 */
    printf("线性表长度:");
    arr_length = GetLength(arrs);
    printf("%d\n", arr_length);
    
    /* 查询元素并返回下标 */
    printf("请输入查询数字:");
    scanf("%d", &cx);
    LocateElemData = LocateElem(arrs, cx);
    if (LocateElemData == -1) printf("该元素不存在!!!\n");
    else printf("该元素下标序号:%d\n", LocateElemData);

    /* 查询位置元素data */
    printf("查询位置元素下标:");
    scanf("%d", &cx);
    GetElem(arrs, cx, &e);
    printf("该元素为:%d\n", e);

    /* 插入元素 */
    printf("请输入插入位置、数字:");
    scanf("%d %d", &i, &e);
    listInsert(arrs, i, e);
    print(arrs);
    arr_length = GetLength(arrs);
    printf("线性表长度:%d\n", arr_length);

    /* 删除元素 */
    printf("请输入删除元素下标序号:");
    scanf("%d", &cx);
    ListDalete_sq(arrs, cx);
    print(arrs); 
    arr_length = GetLength(arrs);
    printf("线性表长度:%d\n", arr_length);
    
    /* 合并表1 2 */
    printf("合并表:");
    mergeTable(arrs, arrs2);
    print(arrs);
    
    /* 有序表3 4合并 */
    printf("有序表顺序存储结构合并:");
    List LC;
    LC = Orderly_merge_table(arrs3, arrs4, LC);
    print(LC);
    return 0;
}


// 初始化表
List InitList_Sq()
{
    List L;
    L = (List)malloc(sizeof(struct LNode));    // 参加存储空间
    if (!L) exit(OVERFLOW);       
    L->Last = -1;                              // 定义线性表的最后一个成员(索引)
    return L;
}
 
/*
*  插入元素
*   List L:  线性表
*   int i :插入位置
*   ElementType* e :插入内容
*/ 
int listInsert(List L, int i, ElementType e)
{
    if(i < 0 || i-1 > L->Last+1 )
    {
        printf("插入元素下标不合法!");
        return ERROR;   
    }  
    if (L->Last == MAXSIZE)
    {
       printf("线性表已满!");
        return ERROR;   
    }
    
    for (int j = L->Last; j >= i; j--){         // 当j大于或大于i时,如果大于表尾直接插入
        L->Data[j + 1] = L->Data[j];            // 从表尾开始到插入元素位置,逐个向后移动1位
    }  
    L->Data[i] = e;                             // 将新内容添加到对应下标位
    L->Last++;                                  // 末位下标+1
}

// 添加元素
int addList(List L, ElementType e)  
{
    if (L->Last != MAXSIZE){
        L->Data[L->Last+1] = e;                 // 末位下标+1插入元素     
        L->Last++;                              // 下标+1
    }
    return OK;
}           

// 输出表
void print(List L)
{
    for (int i = 0; i <= L->Last; i++)          // 遍历表表长度
    {
        printf("%d\t", L->Data[i]);             // 输出
    }
    printf("\n");
}

// 销毁表
void DestroList (List L)
{
    if (L) free(L);  
}

// 置空表
int ClearList(List L)
{
    return L->Last = -1;               
}

// 表长度
int GetLength(List L) 
{
    return L->Last+1;
}
 
// 判断表是否为空
bool isEmpty(List L)
{
    if (L->Last < 0) 
    {
        printf("线性表为空表!!!\n");
        return true;
    }
    printf("线性表为非空表!!!\n");
    return false;
}

/* 查询i位置上元素值:
* List L: 线性表
* i:位置
* ElementType* e:
*/ 
int GetElem(List L, int i, ElementType* e)
{
    if(i < 0 || i >L->Last){             // 判断输入合理?
        printf("%i号下标元素不存在!!!,请输入0-%d\n", i, L->Last);
        return ERROR;   
    }     
    *e = L->Data[i];                     // 指向下标为i的值并返回
    return OK;
}

/*
*  定位元素
*   List L:线性表
*   ElementType* e:对比元素
*/ 
int LocateElem(List L, ElementType e)
{
    for (int i = 0; i <= L->Last; i++)  // 循环L每个元素;
    {
        if(L->Data[i] == e) return i;   // 和e逐个比对,相同返回元素下标;
    }  
    return ERROR;                       // 循环结束未找到对应元素,返回ERROR;
}
int LocateElem2(List L, ElementType e)
{
    int i = 0;
    while (i < L->Last && L->Data[i] != e) i++;
    if(i < L->Last) return ++i;
    return ERROR;
}

 /*
 * 删除元素:
 *   List L:  
 *   int i 
 */ 
int ListDalete_sq(List L, int i)
{
    if(i < 0 || i >L->Last+1){                  // 判断输入是否合理
        printf("%i号下标元素不存在!!!,请输入0-%d\n", i, L->Last);
        return ERROR;
    } 
    if(L->Last == MAXSIZE){                     // 判断是否空间已满
        printf("线性表已存储空间已满!!!\n");
        return ERROR;
    } 
    for (int j = i; j < L->Last; j++)           // 循环元素逐个向前移动1位置
        L->Data[j] = L->Data[j+1];

    L->Last--;                                  // 末位下标-1
    return OK;                          
} 

/* 
 *  合并线性表:
 *     L1:线性表1
 *     L2:线性表2
 * */
void mergeTable(List L1, List L2)
{   
    int e, flag;
    for (int i = 0; i <= L2->Last; i++)         /* 遍历表2获取下标 */
    {
        GetElem(L2, i, &e);                     // 用下标获取L2的data值
        flag = LocateElem(L1, e);               // 判断是否与表1相同,不相同返回-1,相同返回内容
        if (flag == -1)                         // 当L1 L2值不同则插入到L1末尾
        {  
            addList(L1, e);                     // 末位直接插入
        }
    }
}

/* 
 *  有序表合并(顺序存储结构):
 *    List LA:表3
 *    List LB:表4
 *    List *LC:合并后表
 * */
List Orderly_merge_table(List LA, List LB, List LC)
{
    int *Pa, *Pb, *Pc, *Pa_last, *Pb_last;                  // 创建头3指针,尾指针
    Pa = LA->Data;
    Pb = LB->Data;                                          // 获取头元素,用于对比大小
    LC = (List)malloc(sizeof(struct LNode));                // 创建LC表存储空间, 用于存储AB表元素struct LNode
    LC->Last = LA->Last + LB->Last + 1;                     // 创建表C末位下标,因为下标从0开始,所以两表合并需要+1
    Pc = LC->Data;                                          // 指向表C头元素
    Pa_last = LA->Data + LA->Last;
    Pb_last = LB->Data + LB->Last;                          // 获取表尾元素,用于判断表是否为空
    while (Pa <= Pa_last && Pb <= Pb_last )                 // 判断两表非空
    {
        if (*Pa <= *Pb)                                     // 获取最小值加入pc
        {
            *Pc++ = *Pa++;                        
        }else {
            *Pc++ = *Pb++;  
        }
    }   
    while (Pa <= Pa_last)                                   // 判断是否还有元素,有则添加Lc末尾     
    {
        *Pc++ = *Pa++;
    }
    while (Pb <= Pb_last)                                       
    {
        *Pc++ = *Pb++;
    }
    return LC;                                              // 返回给Lc表
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
C语言中的线性表可以通过顺序存储结构来实现。顺序存储结构是指将线性表的元素连续地存储在一块连续的内存空间中,通过元素在内存中的物理地址顺序关系来表示线性表中元素之间的逻辑关系。 在C语言中,可以使用数组来实现顺序存储结构线性表。例如,定义一个包含n个元素的线性表,可以使用一个一维数组来存储。数组的下标表示元素在线性表中的位置,数组元素的值存储着具体的数据。 顺序存储结构线性表具有以下特点: 1. 随机存取:可以通过下标直接访问任意位置的元素,时间复杂度为O(1)。这使得可以以较低的代价访问线性表中的元素。 2. 插入和删除操作效率较低:在顺序存储结构中,如果要在中间位置插入或删除一个元素,需要将插入或删除位置后的所有元素依次往后或往前移动,时间复杂度为O(n),其中n是线性表的长度。 3. 存储空间的浪费:顺序存储结构需要提前分配足够的连续内存空间,如果线性表的长度不确定或经常变化,可能会造成存储空间的浪费。 4. 需要事先知道线性表的大小:在使用顺序存储结构线性表时,需要事先知道线性表的大小,以便分配相应大小的内存空间。 总之,C语言线性表可以通过数组实现顺序存储结构。虽然具有一些限制,但在访问元素方面具有快速的优势,是一种常用的线性表实现方式。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ZiWie丶ZHANG

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值