C语言下的顺序表以及各种链表的实现

1、线性表

1.1、顺序表

scanf和getchar的区别:::info

  1. scanf :无法读取空格,且是输入向
  2. getchar:读取 —>标准输入的数据
  3. 当两个while循环中都有scanf接收输入时:
    1. 可在中间用getchar()吃掉缓冲区的值
    2. 或重新定义变量来接收scanf的返回值
      :::
顺序表的实现过程```c
#ifndef __LIST_H
#define __LIST_H 1
#define SIZE 5		//扩容

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

struct List{		//声明及定义结构体
        int *p;
        int size;
        int index;
}*ps;

extern void list_init(struct List *);		//声明方法
extern void list_add(struct List *,int);
extern void list_print(struct List *);
extern void list_del(struct List *,int);
extern void list_edit(struct List *,int,int);

#endif
#include "list.h"
//初始化结构体,给成员中指针申请堆空间存数据
void list_init(struct List *ps){
        ps->size = SIZE;	//指针p初始化空间大小
        ps->p = (int *)malloc(ps->size * sizeof(int));
        if(ps->p == NULL){
                printf("指针p内存申请失败");
        }
        ps->index = -1;
}
//添加数据到成员p指针的空间里
void list_add(struct List *ps,int data){
        int *temp;
        ps->index++;
        if(ps->index == ps->size){		//超出p空间则扩容
                ps->size += SIZE;
                temp = (int *)realloc(ps->p,ps->size * sizeof(int));
                ps->p = temp;
        }
        ps->p[ps->index] = data;
}
//删除结构体成员p指针里的数据
void list_del(struct List *ps,int data){
        if(ps->index == -1){	//判断为空不处理
                printf("顺序表为空\n");
                return;
        }
        for(int i=0;i<=ps->index;i++){	
                if(ps->p[i] == data){	//遍历找出成员指针p空间的数据
                        for(int j=i;j<=ps->index;j++){
                                ps->p[j] = ps->p[j+1];
                        }
                        ps->index--;
                        return;
                }
        }
}
//修改结构体成员p指针里的数据
void list_edit(struct List *ps,int data,int new_data){
        if(ps->index == -1){	//判断为空不处理
                printf("顺序表为空");
                return;
        }
        for(int i=0;i<=ps->index;i++){
                if(ps->p[i] == data){	//遍历找出成员指针p空间的数据
                        ps->p[i] = new_data;
                }
        }
}
//查询结构体成员p指针里的数据
void list_print(struct List *ps){
        printf("顺序表:");
        for(int i=0;i<=ps->index;i++){	//遍历找出成员指针p空间的数据
            printf("%d-",ps->p[i]);
        }
        printf("\n");
}

#include "list.h"

int main(void){
        int t;
        int data;
        ps = (struct List*)malloc(sizeof(struct List));//给结构体申请堆空间
        if(ps == NULL){
                printf("指针ps内存申请失败");
        }
        list_init(ps);	//初始化结构体
        while(1){		
                printf("插入:");	//增加数据
                t = scanf("%d",&data);
                if(t==0){
                        printf("已退出\n");
                        break;
                }
                list_add(ps,data);
                list_print(ps);		//打印顺序表
        }
        getchar();	//清除缓冲区t的值
        while(1){
                printf("删除:");	//删除数据
                t = scanf("%d",&data);
                if(t == 0){
                        printf("已退出\n");
                        break;
                }
                list_del(ps,data);
                list_print(ps);		//打印顺序表
        }
        getchar();	//清除缓冲区t的值
        int new_data;
        while(1){					//修改数据
                printf("修改值:");
                t = scanf("%d",&data);
                if(t == 0){
                        printf("已退出\n");
                        break;
                }
                printf("修改为:");
                t = scanf("%d",&new_data);
                if(t == 0){
                        printf("已退出\n");
                        break;
                }
                list_edit(ps,data,new_data);
                list_print(ps);		//打印顺序表
        }
        return 0;
}

1.2、链表

无头节点的单链表```c
头文件
#ifndef __LIST_H
#define __LISH_H 1

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

 struct SList{
        int data;
        struct SList *next;
};

struct SList * create_node(int);
extern void list_headadd(struct SList **,int);	//更改头节点必须用址传递
extern void list_tailadd(struct SList **,int);

extern void list_headdel(struct SList **);
extern void list_taildel(struct SList **);
extern void list_del(struct SList **,int);

extern void list_edit(struct SList *,int,int);
extern void list_print(struct SList *);

#endif
```c
.c文件
#include "list.h"
//封装新节点
struct SList *create_node(int data){
        struct SList *pnode = (struct SList *)malloc(sizeof(struct SList));
        if(pnode == NULL){
                printf("创建节点失败\n");
                exit(-1);
        }
        pnode->data = data;
        return pnode;
}
//头插法
void list_headadd(struct SList **phead,int data){
        struct SList *pnode = create_node(data);
        pnode->next = *phead;	//新节点指针指向头指针
        *phead = pnode;		//头指针指向新节点
}
//尾插法
void list_tailadd(struct SList **phead,int data){
        struct SList *pnode = create_node(data);
        if(*phead == NULL){			//如果头指针为空
                pnode->next = NULL;		//新节点指针指向空
                *phead = pnode;		//头指针指向新节点
        }else{
                struct SList *tail = *phead;	//使用局部指针变量代替头指针
                while(tail->next != NULL){		//将该指针移动到尾部
                        tail = tail->next;
                }
                pnode->next = tail->next;		//pnode指向空
                tail->next = pnode;				//链接前面的链表
        }
}
//头删法
void list_headdel(struct SList **phead){
        if(*phead == NULL){			//链表为空则退出
                printf("链表为空\n");
                return;
        }else{
                struct SList *pnode = *phead;	//使用局部指针变量代替头指针
                *phead = pnode->next;		//头指针指向下一个节点
                free(pnode);				//释放上一个节点
        }
}
//尾删法
void list_taildel(struct SList **phead){
        if(*phead == NULL){			//链表为空则退出
                printf("链表为空\n");
                return;
        }
        if((*phead)->next == NULL){		//只有一个节点是
                free(*phead);			//释放该头指针指向的节点
                *phead = NULL;			//头指针指向空
        }else{
                struct SList *tail = *phead;	//当有两个或以上的节点时
                struct SList *prev = NULL;		//保存上一个节点的地址
                while(tail->next != NULL){		//找到尾部
                        prev = tail;
                        tail = tail->next;
                }
                free(tail);		//释放尾指针指向的节点
                tail = NULL;	//防止成为野指针
                prev->next = NULL;	//上一节点指向空
        }
}
//指定删法
void list_del(struct SList **phead,int data){
        if(*phead == NULL){			//链表为空则退出
                printf("链表为空\n");
                return;
        }
        if((*phead)->data == data){		//当第一个节点为指定值时
                struct SList *pnode = *phead;
                *phead = pnode->next;
                free(pnode);
                pnode = NULL;
        }else{
                struct SList *pnode = *phead;	//使用局部指针变量代替头节点
                struct SList *prev = NULL;	//保存上一个节点的地址
                while(pnode->data != data){	//找到该节点的值
                        prev = pnode;
                        pnode = pnode->next;
                }
                if(pnode->data == data){	
                        prev->next = pnode->next;	//跳过中间的节点
                        free(pnode);	//释放节点内存
                        pnode = NULL;	//防止成为野指针
                }else{
                        printf("没有找到指定数据\n");
                }
        }
}
//修改法
void list_edit(struct SList *phead,int data,int new_data){
        struct SList *pnode = phead;	//局部指针变量代替头指针
        if(pnode == NULL){		//链表为空则退出
                printf("链表为空\n");
                return;
        }
        while(pnode->data != data){		//找到需要修改的值对应的节点
                if(pnode->next != NULL){
                        pnode = pnode->next;
                }else{
                        printf("没有找到该数据\n");
                        return;
                }
        }
        if(pnode->data == data){	//修改值
                pnode->data = new_data;
                return;
        }
}
//打印输出
void list_print(struct SList *plist){
        printf("单链表:");
        struct SList *cur = plist;	//使用局部指针代替头指针
        while(cur != NULL){		//不为空时打印出数据
                printf("%d->",cur->data);
                cur = cur->next;	//往下移动
        }
        puts("");
}
```c
```c
main文件
#include "list.h"

int main(void)
{
        struct SList *plist = NULL;	//头指针初始化为空
        int data,temp;
        while(1){
                printf("头插:");
                temp = scanf("%d",&data);
                if(temp == 0){
                        printf("结束头插\n");
                        break;
                }
                list_headadd(&plist,data);	//传头指针地址
                list_print(plist);
        }
        getchar();	//除去缓冲区scanf的返回值,即temp的值
        while(1){
                printf("尾插:");
                temp = scanf("%d",&data);
                if(temp == 0){
                        printf("结束尾插\n");
                        break;
                }
                list_tailadd(&plist,data);
                list_print(plist);
        }
        getchar();
        while(1){
                printf("头删:");
                temp = scanf("%d",&data);
                if(temp == 0){
                        printf("结束头插\n");
                        break;
                }
                list_headdel(&plist);
                list_print(plist);
        }
        getchar();
        while(1){
                printf("尾删:");
                temp = scanf("%d",&data);
                if(temp == 0){
                        printf("结束尾删\n");
                        break;
                }
                list_taildel(&plist);
                list_print(plist);
        }
        getchar();
        while(1){
                printf("指定删除:");
                temp = scanf("%d",&data);
                if(temp == 0){
                        printf("结束删除\n");
                        break;
                }
                list_del(&plist,data);
                list_print(plist);
        }
        getchar();
        while(1){
                printf("修改:\n");
                int new_data;
                printf("修改值:");
                temp = scanf("%d",&data);
                if(temp == 0){
                        printf("结束修改\n");
                        break;
                }
                printf("修改为:");
                temp = scanf("%d",&new_data);
                if(temp == 0){
                        printf("结束修改\n");
                        break;
                }
                list_edit(plist,data,new_data);
                list_print(plist);
        }
        return 0;
}

总结无头单链表:
传入头节点的二级指针,即头指针的地址 &phead

```c
有头节点的单链表```c
头文件
#ifndef __LINK_H
#define __LINK_H 1

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

typedef struct Link{
        int data;
        struct Link *next;
}Link,*pLink;

extern pLink link_init();
extern void link_h_add(pLink ,int);
extern void link_t_add(pLink ,int);
extern void link_del(pLink ,int);
extern void link_edit(pLink ,int,int);
extern void link_print(pLink);

#endif
```c
.c文件
#include "link.h"

pLink link_init(){
        pLink phead = (pLink)malloc(sizeof(Link));
        if(phead == NULL){
                perror("分配内存失败\n");
                exit(-1);
        }
        phead->next = NULL;
        return phead;
}

void link_h_add(pLink phead,int data){
        pLink pnode = (pLink)malloc(sizeof(Link));
        if(pnode == NULL){
                perror("分配内存失败\n");
                exit(-1);
        }
        pnode->data = data;
        pnode->next = phead->next;
        phead->next = pnode;
}
void link_t_add(pLink phead,int data){
        pLink pnode = (pLink)malloc(sizeof(Link));
        if(pnode == NULL){
                perror("分配内存失败\n");
                exit(-1);
        }
        pnode->data = data;
        while(phead->next != NULL){
                phead = phead->next;
        }
        pnode->next = phead->next;
        phead->next = pnode;
}
void link_del(pLink phead,int data){
    //1、判断为空 2、while遍历查找 3、定义指针指向该删除节点
        if(phead->next == NULL){
                printf("链表为空\n");
                return;
        }
        while(phead->next != NULL){
                if(phead->next->data == data){
                        pLink p = phead->next;
                        phead->next = p->next;
                        p->next = NULL;
                        free(p);
                        return;
                }
                phead = phead->next;
        }
        printf("没有找到该数据\n");
}
void link_edit(pLink phead,int data,int new){
    //1、判断为空 2、定义指针指向该修改节点 3、创建新节点替换
        if(phead->next == NULL){
                printf("链表为空\n");
                return;
        }
        while(phead->next != NULL){
                if(phead->next->data == data){
                        pLink p = phead->next;
                        pLink pnew = (pLink)malloc(sizeof(Link));
                        if(pnew == NULL){
                                printf("分配内存失败\n");
                                exit(-1);
                        }
                        pnew->next = p->next;
                        pnew->data = new;
                        phead->next = pnew;
                        p->next = NULL;
                        free(p);
                        return;
                }
                phead = phead->next;
        }
        printf("没有找到该数据\n");
}
void link_print(pLink phead){
        if(phead->next == NULL){
                printf("链表为空\n");
                return;
        }
        while(phead->next != NULL){
                printf("%d->",phead->next->data);
                phead = phead->next;
        }
        printf("NULL");
        puts("");
}
```c
```c
main文件
#include "link.h"

int main(void)
{
        pLink phead = link_init();
        printf("初始化完毕\n");

        int temp,data;
        while(-1){
                temp = scanf("%d",&data);
                if(temp == 0){
                        printf("结束头插\n");
                        break;
                }
                link_h_add(phead,data);
                link_print(phead);
        }
        getchar();
        while(-1){
                temp = scanf("%d",&data);
                if(temp == 0){
                        printf("结束尾插\n");
                        break;
                }
                link_t_add(phead,data);
                link_print(phead);
        }
        getchar();
        while(-1){
                printf("删除:");
                temp = scanf("%d",&data);
                if(temp == 0){
                        printf("结束删除\n");
                        break;
                }
                link_del(phead,data);
                link_print(phead);
        }
        getchar();
        while(-1){
                printf("修改:\n");
                printf("修改值:");
                temp = scanf("%d",&data);
                if(temp == 0){
                        printf("结束修改\n");
                        break;
                }
                int new;
                printf("修改为:");
                temp = scanf("%d",&new);
                if(temp == 0){
                        printf("结束修改\n");
                        break;
                }
                link_edit(phead,data,new);
                link_print(phead);
        }
        return 0;
}

```c

总结有头单链表:

  1. 删除函数里定义游标指向要删除的节点,释放再置空
  2. 修改函数里也是用游标指定修改的节点,再用新数据创建新结构体指针来替换
```c
单向循环链表```c
头文件
#ifndef __LINK_H
#define __LINK_H 1

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

typedef struct SLink{
        int data;
        struct SLink *next;
}Link,*pLink;

extern pLink link_init();
extern pLink create_node(int);
extern void link_h_add(pLink ,int);
extern void link_t_add(pLink ,int);
extern void link_del(pLink,int);
extern void link_edit(pLink,int,int);
extern void link_print(pLink);

#endif
```c
```c
.c文件
#include "link.h"

pLink link_init(){
        pLink phead = (pLink)malloc(sizeof(Link));
        if(phead == NULL){
                perror("分配内存失败\n");
                exit(-1);
        }
        phead->next = phead;
        return phead;
}
pLink create_node(int data){
        pLink pnode = (pLink)malloc(sizeof(Link));
        if(pnode == NULL){
                perror("分配内存失败\n");
                exit(-1);
        }
        pnode->data = data;
        return pnode;
}
void link_h_add(pLink phead,int data){
        pLink pnode = create_node(data);
        if(pnode == NULL){
                return;
        }
        pnode->next = phead->next;
        phead->next = pnode;
}
void link_t_add(pLink phead,int data){
        pLink pnode = create_node(data);
        pLink p = phead;
        while(p->next != phead){
                p = p->next;
        }
        pnode->next = p->next;
        p->next = pnode;
}
void link_del(pLink phead,int data){
        if(phead->next == phead){
                printf("链表为空\n");
                return;
        }
        pLink p = phead;
        while(p->next != phead){
                if(p->next->data == data){
                        pLink pd = p->next;
                        p->next = pd->next;
                        pd->next = NULL;
                        free(pd);
                        return;
                }
                p = p->next;
        }
        printf("没有找到该数据\n");
}
void link_edit(pLink phead,int data,int new){
        if(phead->next == phead){
                printf("链表为空\n");
                return;
        }
        pLink p = phead;
        while(p->next != phead){
                if(p->next->data == data){
                        pLink pe = p->next;
                        pLink pnew = create_node(new);
                        pnew->next = pe->next;
                        p->next = pnew;
                        pe->next = NULL;
                        free(pe);
                        return;
                }
                p = p->next;
        }
        printf("没有找到该数据\n");
}
void link_print(pLink phead){
        if(phead->next == phead){
                printf("链表为空\n");
                return;
        }
        pLink p = phead;
        while(p->next != phead){
                printf("%d->",p->next->data);
                p = p->next;
        }
        printf("head");
        puts("");
}
```c
main文件
```c
#include "link.h"

int main(void)
{
        pLink phead = link_init();
        printf("初始化完毕\n");

        int temp,data;
        while(1){
                printf("头插:");
                temp = scanf("%d",&data);
                if(temp == 0){
                        printf("结束头插\n");
                        break;
                }
                link_h_add(phead,data);
                link_print(phead);
        }
        getchar();
        while(1){
                printf("尾插:");
                temp = scanf("%d",&data);
                if(temp == 0){
                        printf("结束尾插\n");
                        break;
                }
                link_t_add(phead,data);
                link_print(phead);
        }
        getchar();
        while(1){
                printf("删除:");
                temp = scanf("%d",&data);
                if(temp == 0){
                        printf("结束删除\n");
                        break;
                }
                link_del(phead,data);
                link_print(phead);
        }
        getchar();
        printf("修改:\n");
        int new;
        while(1){
                printf("修改值:");
                temp = scanf("%d",&data);
                if(temp == 0){
                        printf("结束修改\n");
                        break;
                }
                printf("修改为:");
                temp = scanf("%d",&new);
                if(temp == 0){
                        printf("结束修改\n");
                        break;
                }
                link_edit(phead,data,new);
                link_print(phead);
        }
        return 0;
}

总结单向循环链表:

  1. 末尾节点指向头head
  2. 传入头节点head遍历移动链表时要用游标代替头节点head
```c
双向链表```c
头文件
#ifndef __LINK_H
#define __LINK_H 1

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

typedef struct DLink{
        int data;
        struct DLink *prev;
        struct DLink *next;
}Link,*pLink;

extern pLink link_init();
extern pLink create_node(int data);
extern void link_h_add(pLink,int);
extern void link_t_add(pLink,int);
extern void link_del(pLink,int);
extern void link_edit(pLink,int,int);
extern void link_print(pLink);

#endif
```c
```c
.c文件
#include "link.h"

pLink link_init(){
        pLink phead = (pLink)malloc(sizeof(Link));
        if(phead == NULL){
                perror("init error\n");
                exit(-1);
        }
        phead->prev = NULL;
        phead->next = NULL;
        return phead;
}
pLink create_node(int data){
        pLink pnode = link_init();
        pnode->data = data;
        return pnode;
}
void link_h_add(pLink phead,int data){
        pLink pnode = create_node(data);
        pnode->next = phead->next;
        pnode->prev = phead;
        phead->next = pnode;
}
void link_t_add(pLink phead,int data){
        pLink pnode = create_node(data);
        pLink pos = phead;
        while(pos->next != NULL){
                pos = pos->next;
        }
        pnode->next = pos->next;
        pnode->prev = pos;
        pos->next = pnode;
}
void link_del(pLink phead,int data){
        if(phead->next == NULL){
                printf("链表为空\n");
                return;
        }
        pLink pos = phead;
        while(pos->next != NULL){
                if(pos->next->data == data){
                        pLink pdel = pos->next;
                        if(pdel->next == NULL){
                                pos->next = pdel->next;
                        }else{
                                pdel->next->prev = pos;
                                pos->next = pdel->next;
                        }
                        free(pdel);
                        pdel = NULL;
                        return;
                }
                pos = pos->next;
        }
        printf("没有找到该数据\n");
}
void link_edit(pLink phead,int data,int new){
        if(phead == NULL){
                printf("链表为空\n");
                return;
        }
        pLink pos = phead;
        while(pos->next != NULL){
                if(pos->next->data == data){
                        pLink pnew = create_node(new);
                        pLink pold = pos->next;
                        pnew->prev = pos;
                        pnew->next = pold->next;
                        pos->next = pnew;
                        free(pold);
                        pold = NULL;
                        return;
                }
                pos = pos->next;
        }
        printf("没有找到该数据\n");
}
void link_print(pLink phead){
        if(phead->next == NULL){
                printf("链表为空\n");
                return;
        }
        pLink pos = phead;
        while(pos->next != NULL){
                printf("%d->",pos->next->data);
                pos = pos->next;
        }
        puts("");
}
```c
```c
main文件
#include "link.h"

int main(void){
        pLink phead = link_init();
        printf("初始化完毕\n");

        int temp,data;
        while(1){
                printf("头插:");
                temp = scanf("%d",&data);
                if(temp == 0){
                        printf("结束头插\n");
                        break;
                }
                link_h_add(phead,data);
                link_print(phead);
        }
        getchar();
        while(1){
                printf("尾插:");
                temp = scanf("%d",&data);
                if(temp == 0){
                        printf("结束尾插\n");
                        break;
                }
                link_t_add(phead,data);
                link_print(phead);
        }
        getchar();
        while(1){
                printf("删除:");
                temp = scanf("%d",&data);
                if(temp == 0){
                        printf("结束删除\n");
                        break;
                }
                link_del(phead,data);
                link_print(phead);
        }
        getchar();
        printf("修改:\n");
        int new;
        while(1){
                printf("修改值:");
                temp = scanf("%d",&data);
                if(temp == 0){
                        printf("结束修改\n");
                        break;
                }
                printf("修改为:");
                temp = scanf("%d",&new);
                if(temp == 0){
                        printf("结束修改\n");
                        break;
                }
                link_edit(phead,data,new);
                link_print(phead);
        }

        return 0;
}

总结双向链表:

  1. 多一个prev前驱指针域
  2. 在删和改某个节点时,分两种情况
    1. 一是需要修改该节点再下一个节点的prev指针域
    2. 二是最后一个节点时,再下一个节点就为NULL,NULL没有prev指针域
```c
双向循环链表```c
#ifndef __LINK_H
#define __LINK _H 1

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

typedef struct DLink{
        int data;
        struct DLink *prev;
        struct DLink *next;
}Link,*pLink;

extern pLink link_init();
extern pLink create_node(int);
extern void link_h_add(pLink,int);
extern void link_t_add(pLink,int);
extern void link_del(pLink,int);
extern void link_edit(pLink,int,int);
extern void link_print(pLink);

#endif
```c
.c文件
#include "link.h"

pLink link_init(){
        pLink phead = (pLink)malloc(sizeof(Link));
        if(phead == NULL){
                perror("分配内存失败\n");
                exit(-1);
        }
        phead->next = phead;
        phead->prev = phead;
        return phead;
}
pLink create_node(int data){
        pLink pnode = (pLink)malloc(sizeof(Link));
        if(pnode == NULL){
                perror("分配内存失败\n");
                exit(-1);
        }
        pnode->data = data;
        return pnode;
}
void link_h_add(pLink phead,int data){
        pLink pnode = create_node(data);
        pLink p = phead;
        pnode->next = p->next;
        pnode->prev = p;
        p->next = pnode;
}
void link_t_add(pLink phead,int data){
        pLink pnode = create_node(data);
        pLink p = phead;
        while(p->next != phead){
                p = p->next;
        }
        pnode->next = p->next;
        pnode->prev = p;
        p->next = pnode;
        phead->prev = pnode;
}
void link_del(pLink phead,int data){
        if(phead->next == NULL){
                printf("链表为空\n");
                return;
        }
        pLink p = phead;
        while(p->next != phead){
                if(p->next->data == data){
                        pLink pd = p->next;
                        p->next = pd->next;
                        pd->next->prev = p;
                        pd->next = NULL;
                        pd->prev = NULL;
                        free(pd);
                        return;
                }
                p = p->next;
        }
        printf("没有找到该数据\n");
}
void link_edit(pLink phead,int data,int new){
        if(phead->next == NULL){
                printf("链表为空\n");
                return;
        }
        pLink p = phead;
        while(p->next != phead){
                if(p->next->data == data){
                        pLink pe = p->next;
                        pLink pnew = create_node(new);
                        pnew->next = pe->next;
                        pnew->prev = pe->prev;
                        p->next = pnew;
                        pe->next->prev = pnew;
                        pe->next = NULL;
                        pe->prev = NULL;
                        free(pe);
                        return;
                }
                p = p->next;
        }
        printf("没有找到该数据\n");
}
void link_print(pLink phead){
        pLink p = phead;
        if(p->next == NULL){
                printf("链表为空\n");
                return;
        }
        while(p->next != phead){
                printf("%d->",p->next->data);
                p = p->next;
        }
        puts("");
}

```c
main文件
#include "link.h"

int main(void)
{
        pLink phead = link_init();
        printf("初始化完毕\n");

        int temp,data,new;
        while(1){
                printf("头插:");
                temp = scanf("%d",&data);
                if(temp == 0){
                        printf("结束头插\n");
                        break;
                }
                link_h_add(phead,data);
                link_print(phead);
        }
        getchar();
        while(1){
                printf("尾插:");
                temp = scanf("%d",&data);
                if(temp == 0){
                        printf("结束尾插\n");
                        break;
                }
                link_t_add(phead,data);
                link_print(phead);
        }
        getchar();
        while(1){
                printf("删除:");
                temp = scanf("%d",&data);
                if(temp == 0){
                        printf("结束删除\n");
                        break;
                }
                link_del(phead,data);
                link_print(phead);
        }
        getchar();
        printf("修改:\n");
        while(1){
                printf("修改值:");
                temp = scanf("%d",&data);
                if(temp == 0){
                        printf("结束修改\n");
                        break;
                }
                printf("修改为:");
                temp = scanf("%d",&new);
                if(temp == 0){
                        printf("结束修改\n");
                        break;
                }
                link_edit(phead,data,new);
                link_print(phead);
        }
        return 0;
}

总结双向循环链表:

  1. 头节点两指针域都指向自己
  2. 插入节点要改变四个指针域
  3. 传入头节点head遍历移动链表时要用游标代替头节点head
``
```c
头文件
(ps:需要自行找内核文件,这里暂不提供)
#ifndef __LINK_H
#define __LINK_H 1

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

typedef struct Link{
        int data;
        struct list_head node;
}Link,*pLink;

extern pLink link_init();
extern pLink create_note(int data);
extern void link_h_add(pLink,int);
extern void link_t_add(pLink,int);
extern void link_del(pLink,int);
extern void link_edit(pLink,int,int);
extern void link_print(pLink);

#endif
``
```c
```c
.c文件
#include "link.h"

pLink link_init(){
        pLink phead = (pLink)malloc(sizeof(Link));
        if(phead == NULL){
                perror("初始化头节点失败\n");
                exit(-1);
        }
        INIT_LIST_HEAD(&phead->node);
        return phead;
}

pLink create_node(int data){
        pLink pnode = (pLink)malloc(sizeof(Link));
        if(pnode == NULL){
                perror("初始化节点失败\n");
                exit(-1);
        }
        pnode->data = data;
        return pnode;
}

void link_h_add(pLink phead,int data){
        pLink pnew = create_node(data);
        list_add(&pnew->node,&phead->node);
}
void link_t_add(pLink phead,int data){
        pLink pnew = create_node(data);
        list_add_tail(&pnew->node,&phead->node);
}
void link_del(pLink phead,int data){
        pLink pos;
        list_for_each_entry(pos,&phead->node,node){
                if(pos->data == data){
                        list_del(&pos->node);
                        free(pos);
                        return;
                }
        }
}
void link_edit(pLink phead,int data,int new){
        pLink pos;
        pLink pnew = create_node(new);
        list_for_each_entry(pos,&phead->node,node){
                if(pos->data == data){
                        list_replace_init(&pos->node,&pnew->node);
                        free(pos);
                        return;
                }
        }
        printf("没有找到该数据\n");
}
void link_print(pLink phead){
        pLink pos;
        list_for_each_entry(pos,&phead->node,node){
                printf("%d->",pos->data);
        }
        puts("");
}

```c
main文件
#include "link.h"

int main(){
        pLink phead = link_init();
        printf("初始化完毕\n");
        int temp,data;
        while(1){
                printf("头插:");
                temp = scanf("%d",&data);
                if(temp == 0){
                        printf("结束头插\n");
                        break;
                }
                link_h_add(phead,data);
                link_print(phead);
        }
        getchar();
        while(1){
                printf("尾插:");
                temp = scanf("%d",&data);
                if(temp == 0){
                        printf("结束尾插\n");
                        break;
                }
                link_t_add(phead,data);
                link_print(phead);
        }
        getchar();
        while(1){
                printf("删除:");
                temp = scanf("%d",&data);
                if(temp == 0){
                        printf("结束删除\n");
                        break;
                }
                link_del(phead,data);
                link_print(phead);
        }
        getchar();
        int new;
        printf("修改:\n");
        while(1){
                printf("修改值:");
                temp = scanf("%d",&data);
                if(temp == 0){
                        printf("结束修改\n");
                        break;
                }
                printf("修改为:");
                temp = scanf("%d",&new);
                if(temp == 0){
                        printf("结束修改\n");
                        break;
                }
                link_edit(phead,data,new);
                link_print(phead);
        }
        return 0;
}

总结内核链表:

  1. 头文件引入kernel内核文件
  2. 使用内核函数只需传入
    1. 头指针的子头指针(&phead->node)
    2. 数据指针的子结构体指针(&pnode->node)
    3. 遍历的指针(pos)子头指针(&phead->node)子结构体名称(node)
  3. 常用的内核函数
    1. 初始化 INIT_LIST_HEAD(&phead->node);
    2. 头插 list_add(&pnew->node,&phead->node);
    3. 尾插 list_add_tail(&pnew->node,&phead->node);
    4. 遍历 list_for_each_entry(pos,&phead->node,node){}
    5. 删除 list_del(&pos->node);
    6. 修改 list_replace_init(&pos->node,&pnew->node);
      ``
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值