Sequence list and linked list of data structure

Table of contents

1. The basic concept of data structure

Edit 2. Sequence list and linked list

 2.1 Sequence table creation and algorithm

 2.1.1 Construction of sequence table (taking student performance management as an example)

 2.1.2 Creation of sequence table (construction function)

 2.1.3 Insertion of members in the sequence table (construction function)

 2.1.4 Deletion of members in the sequence table (construction function)

 2.1.5 Member data modification in the sequence table (construction function) 

 2.1.6. Sort (constructor)

 2.1.7 Release of sequence table

 2.2 Creation and algorithm of headed singly linked list

 2.2.1 Construction of linked list

  2.1.2 Linked list creation (construction function)

 2.1.3 Insertion of linked list members (construction function) 

2.1.4 Deletion of linked list members (construction function)

 2.1.5 Sorting of linked list (construction function)

 2.1.6 Flipping of linked list (construction function)

 2.1.7 Traversal and release of linked list (construction function)


1. The basic concept of data structure

 2. Sequence list and linked list

 2.1 Sequence table creation and algorithm

 2.1.1 Construction of sequence table (taking student performance management as an example)

//数据类型
typedef struct stu
{
    char name[20];
    unsigned char age;
    unsigned short sco;
}Stu_t;

//顺序表数据类型
typedef struct list
{
    Stu_t list[N];  //顺序表结构
    unsigned index; //用于记录顺序表使用情况(0~N)
}Seqlist_t;

 2.1.2 Creation of sequence table (construction function)

//创建顺序表
Seqlist_t *create_list(void){
    Seqlist_t *L = (Seqlist_t *)malloc(sizeof(Seqlist_t));    //申请堆区空间
    if (NULL == L)
    {
        puts("创建顺序表失败");
        exit -1;
    }
    memset(L,0,sizeof(Seqlist_t));    //初始化顺序表

    L->index = 0;
    return L;
}

 2.1.3 Insertion of members in the sequence table (construction function)

Insert a member anywhere in the sequence table

// 任意位置插入数据
int insert_data(Seqlist_t *L,unsigned pos,Stu_t data){
    //健壮性判断
    if (NULL == L)
    {
        puts("传参为空");
        return -1;
    }
    if (N == L->index)
    {
        puts("表已满 插入失败");
        return -1;
    }
    if (pos > L->index)
    {
        puts("插入位置不合理");
        printf("位置范围为:0<=pos<%d\n",L->index);
        return -1;
    }
    int i = 0;
    for (i = L->index; i > pos; i--)
    {
        L->list[i] = L->list[i-1];    //需要将表中插入位置及之后的数据整体向后移动
    }
    L->list[pos] = data;    //给所需要插入的位置重新赋值
    L->index++;    //顺序表有效成员个数加1
    return 0;
}

 2.1.4 Deletion of members in the sequence table (construction function)

//任意位置删除数据
int delete_data(Seqlist_t *L,int pos){
    //健壮性判断
    if (NULL == L)
    {
        puts("传参为空");
        return -1;
    }
    if (0 == L->index)
    {
        puts("表空 删除失败");
        return -1;
    }
    if (pos >= L->index)
    {
        puts("删除位置不合理");
        printf("位置范围为:0<=pos<%d\n",L->index-1);
        return -1;
    }
    int i = 0;
    for (i = pos; i < L->index-1; i++)
    {
        L->list[i] = L->list[i+1];    //将所需要删除位置之后的所有成员向前移动
                                        //整体向前覆盖一个位置
    }
    --L->index;    //顺序表有效成员个数减1
    return 0;
}

 2.1.5 Member data modification in the sequence table (construction function) 

//去除重名学生元素
int del_same_data(Seqlist_t *L);

//查找数据(根据姓名)
int find_data(Seqlist_t *L,char *f_name);

//修改数据(根据姓名)
int modify_data(Seqlist_t *L,char *f_name,Stu_t data);


//去除重名学生元素
int del_same_data(Seqlist_t *L){
    //健壮性判断
    if (NULL == L)
    {
        puts("传参为空");
        return -1;
    }
    if (0 == L->index)
    {
        puts("表空 操作失败");
        return -1;
    }
    if (1 == L->index)
    {
        puts("只有一个成员,无重名");
        return -1;
    }
    int i = 0;
    int j = 0;
    int num = L->index;
    for (i = 0; i < L->index; i++)
    {
        for (j = i+1; j < L->index; j++)
        {
            if (0==strcmp(L->list[i].name,L->list[j].name))
            {
                delete_data(L,j);
                j--;
            }
        }
    }
    if (num == L->index)
    {
        puts("无重名");
    }
    return 0;
}

//查找数据(根据姓名)
int find_data(Seqlist_t *L,char *f_name){
    //健壮性判断
    if (NULL == L || NULL == f_name)
    {
        puts("传参为空");
        return -1;
    }
    int i = 0;
    Stu_t temp = L->list[i];
    while (0 != strcmp(f_name,temp.name))
    {
        temp = L->list[++i];
        if (i >= L->index)
        {
            puts("未找到该成员");
            return -1;
        }
    }
    printf("检索成功->姓名为:%-10s 年龄为:%-5d 成绩为:%-5d\n",\
        L->list[i].name,L->list[i].age,L->list[i].sco);
        putchar(10);
    return 0;
}

//修改数据(根据姓名)
int modify_data(Seqlist_t *L,char *f_name,Stu_t data){
    //健壮性判断
    if (NULL == L || NULL == f_name)
    {
        puts("传参为空");
        return -1;
    }else if(0 == L->index)
    {
        puts("表空 操作失败");
        return -1;
    }
    int i = 0;
    Stu_t temp = L->list[i];
    while (0 != strcmp(f_name,temp.name))
    {
        temp = L->list[++i];
        if (i >= L->index)
        {
            puts("未找到该成员");
            return -1;
        }
    }
    printf("检索成功->姓名为:%-10s 年龄为:%-5d 成绩为:%-5d\n",\
        L->list[i].name,L->list[i].age,L->list[i].sco
        );
    L->list[i] = data;
    puts("修改成功!");
    return 0;
}

 2.1.6. Sort (constructor)

//根据成绩排序
int sort_list(Seqlist_t *L);

//遍历顺序表
int show_list(Seqlist_t *L);

//根据成绩排序
int sort_list(Seqlist_t *L){
    //健壮性判断
    if (NULL == L)
    {
        puts("传参为空");
        return -1;
    }
    if (0 == L->index)
    {
        puts("表空 排序失败");
        return -1;
    }
    if (1 == L->index)
    {
        puts("只有一个成员,无需排序");
        return -1;
    }
    int flag = 0;    //采用标志位的方式降低冒泡排序的时间复杂度
    for (int i = 0; i < L->index-1; i++)
    {
        for (int j = 0; j < L->index-1-i; j++)
        {
            if (L->list[j].sco > L->list[j+1].sco)
            {
                flag = 1;
                Stu_t temp;
                temp = L->list[j];
                L->list[j] = L->list[j+1];
                L->list[j+1] = temp;
            }
        }
        if(0 == flag)
        break;
    }
    return 0;
}


//遍历顺序表
int show_list(Seqlist_t *L){
    //健壮性判断
    if (NULL == L)
    {
        puts("传参为空");
        return -1;
    }
    if (0 == L->index)
    {
        puts("表为空 遍历失败");
        return -1;
    }
    for (int i = 0; i < L->index; i++)
    {
        printf("         姓名为:%-10s 年龄为:%-5d 成绩为:%-5d\n",\
        L->list[i].name,L->list[i].age,L->list[i].sco
        );
    }
    return 0;
}

 2.1.7 Release of sequence table

//释放顺序表 
int free_list(Seqlist_t **L){
    //健壮性判断
    if (NULL == L || NULL == *L)
    {
        puts("传参为空");
        return -1;
    }
    free(*L);
    *L = NULL;
    return 0;
} 

 2.2 Creation and algorithm of headed singly linked list

 2.2.1 Construction of linked list

//数据结构体
typedef int data_t; 
//链表结构体(成员结构体)
typedef struct node 
{
    data_t data;
    struct node *next; 
}Node_t;

  2.1.2 Linked list creation (construction function)

Node_t *create_list(void){
    Node_t *L = (Node_t *)malloc(sizeof(Node_t));
    if (NULL == L)
    {
        puts("<<创建链表失败/创建结点失败>>");
        exit -1;
    }
    memset(L,0,sizeof(Node_t));
    L->next = NULL;
    return L;
}

 2.1.3 Insertion of linked list members (construction function) 

How to insert into a singly linked list

//头插法
int head_insert(Node_t *L,data_t data);

//尾插法
int tail_insert(Node_t *L,data_t data);

//任意位置插入
int pos_insert(Node_t *L,unsigned int pos,data_t data);

//头插法
int head_insert(Node_t *L,data_t data){
    //健壮性判断
    if (NULL == L)
    {
        puts("<<传参为空>>");
        return -1;
    }
    int i = 0;
    Node_t *newnode = create_list();    //创建新的节点
    newnode->data = data;    //给新节点赋值
    newnode->next = L->next;    //让新节点指向头节点的下一个节点
    L->next = newnode;    //让头节点指向新节点
   return 0;
}

//尾插法
int tail_insert(Node_t *L,data_t data){
    //健壮性判断
    if (NULL == L)
    {
        puts("<<传参为空>>");
        return -1;
    }
    if (NULL == L->next)
    {
        head_insert(L,data);
        return 0;
    }
    
    Node_t *newnode = create_list();
    if(NULL != newnode->next){
        puts("<<新节点创建失败>>");
        return -1;
    }
    newnode->data = data;    //给新节点赋值
    newnode->next = NULL;
    Node_t *temp = L->next;    //使用临时指针变量保存链表
    while (NULL != temp->next)    //循环找到链表最后一个成员
    {
        temp = temp->next;
    }
    temp->next = newnode;    //让最后一个成员指向新节点
    return 0;
}

//任意位置插入
int pos_insert(Node_t *L,unsigned int pos,data_t data){
    //健壮性判断
    if (NULL == L)
    {
        puts("<<传参为空>>");
        return -1;
    }
    //表空判断
    if (NULL == L->next)
    {
        head_insert(L,data);
        return 0;
    }
    Node_t *newnode = create_list();    //给新节点分配空间
    newnode->data = data;    //给新节点赋值
    Node_t *temp = L;    //创建临时变量保存链表
    //插入位置合理性判断
    for (int i = 0; i < pos-1; i++)
    {
        temp = temp->next;
        if (NULL == temp)
        {
            puts("<<插入位置错误>>");
            free(newnode);    //如果插入位置不合理需要释放之前给新节点申请的空间
            return -1;
        }
    }
    //插入操作
    newnode->next = temp->next;
    temp->next = newnode;
    return 0;
}

2.1.4 Deletion of linked list members (construction function)

//头部删除
int head_delet(Node_t *L);

//尾部删除
int tail_delet(Node_t *L);

//任意位置删除
int pos_dleet(Node_t *L,unsigned int pos);

//头部删除
int head_delet(Node_t *L){
    //健壮性判断
    if (NULL == L)
    {
        puts("<<传参为空>>");
        return -1;
    }
    if (NULL == L->next)
    {
        puts("<<表为空 删除失败>>");
        return -1;
    }
    Node_t *del = L->next;
    L->next = del->next;
    free(del);
    del = NULL;
    return 0;
}

//尾部删除
int tail_delet(Node_t *L){
    //健壮性判断
    if (NULL == L)
    {
        puts("<<传参为空>>");
        return -1;
    }
    //表空判断
    if (NULL == L->next)
    {
        puts("<<表为空 删除失败>>");
        return -1;
    }
    //成员唯一判断
    //如果不判断,当成员唯一时,链表尾的查找会越界
    if (NULL == L->next->next)
    {
        head_delet(L);
        return 0;
    }
    Node_t *temp = L; 
    while (NULL != temp->next->next)    //注意越界
    {
        temp = temp->next;
    }
    Node_t *del = temp->next;
    temp->next = NULL;
    free(del);
    return 0;
}

//任意位置删除
int pos_dleet(Node_t *L,unsigned int pos){
    //健壮性判断
    if (NULL == L)
    {
        puts("<<传参为空>>");
        return -1;
    }
    //表空判断
    if (NULL == L->next)
    {
        puts("<<表空,删除失败>>");
        return -1;
    }
    //成员唯一判断
    if (NULL == L->next->next)
    {
        head_delet(L);
        return 0;
    }
    Node_t *delnode = create_list();
    Node_t *temp = L;
    //删除位置合理性判断
    for (int i = 0; i < pos-1; i++)
    {
        temp = temp->next;
        if (NULL == temp->next)
        {
            puts("<<删除位置错误>>");
            free(delnode);
            return -1;
        }
    }
    delnode = temp->next;
    temp->next = delnode->next;
    free(delnode);
    return 0;
}

 2.1.5 Sorting of linked list (construction function)

//链表排序
int sort_list(Node_t *L){
    //健壮性判断
    if (NULL == L)
    {
        puts("<<传参为空>>");
        return -1;
    }
    //表空判断
    if (NULL == L->next)
    {
        puts("<<表空,删除失败>>");
        return -1;
    }
    //成员唯一判断
    if (NULL == L->next->next)
    {
        head_delet(L);
        return 0;
    }
    //通过创建两个指针 先后遍历链表进行数据比较
    Node_t *first = L->next;
    Node_t *second = first->next;
    data_t temp = 0;
    while (NULL != first->next)    //冒泡排序的思想
    {
        while (NULL != second)
        {
            if (first->data <= second->data)    //判断为真 交换数据
            {
                temp = first->data;
                first->data = second->data;
                second->data = temp;
            }
            second = second->next;    //第二个指针向后走
        }
        first = first->next;    //数据交换成功 两个指针同时向后走
        second = first->next;
    }
    return 0;
}

 2.1.6 Flipping of linked list (construction function)

//链表的反转
int reversal_list(Node_t *L){
    //健壮性判断
    if (NULL == L)
    {
        puts("<<传参为空>>");
        return -1;
    }
    //表空判断
    if (NULL == L->next)
    {
        puts("<<表空,反转失败>>");
        return -1;
    }
    //成员唯一判断
    if (NULL == L->next->next)
    {
        puts("<<只有一个成员无需反转>>");
        return 0;
    }

    //方法一
    Node_t *new_L = L->next->next;
    L->next->next = NULL;
    Node_t *temp = new_L;
    while (NULL != new_L)
    {
        temp = temp->next;
        new_L->next = L->next;
        L->next = new_L;
        new_L = temp;
    }
    //方法二
    // Node_t *temp = L->next;
    // Node_t *new_L = L;
    // new_L->next = NULL;
    // while (NULL != temp)
    // {
    //     head_insert(new_L,temp->data);
    //     temp = temp->next;
    // }
    return 0;
}

 2.1.7 Traversal and release of linked list (construction function)

//遍历链表
int show_list(Node_t *L);

//释放链表
int free_list(Node_t **L);

//遍历链表
int show_list(Node_t *L){
    //健壮性判断
    if (NULL == L)
    {
        puts("<<传参为空>>");
        return -1;
    }
    Node_t *temp = L->next;
    while (NULL!= temp)
    {
        printf("%d\n",temp->data);
        temp = temp->next;
    }
}

//释放链表
int free_list(Node_t **L){
    //健壮性判断
    if (NULL == L || NULL == *L)
    {
        puts("<<传参为空>>");
        return -1;
    }
    //方法一
    Node_t *temp = *L;
    Node_t *fr_temp = NULL;
    while (NULL != temp->next)
    {
        fr_temp = temp->next;
        temp->next = fr_temp->next;
        free(fr_temp);
        fr_temp = NULL;
    }
    free(temp);
    temp = NULL;
    *L = NULL;
    //方法二
    // Node_t *temp = *L;
    // while (NULL!=(*L))
    // {
    //     temp = (*L)->next;
    //     printf("%d 节点将会被释放\n",(*L)->data);
    //     free(*L);
    //     *L = temp;
    // }
    return 0;
}

Guess you like

Origin blog.csdn.net/Little_Star0/article/details/128959111