c语言单链表代码

`

#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
typedef int ElementType; // 定义数据类型,可根据需要进行其他类型定义
// 链表节点的定义
typedef struct ListNode {
ElementType Element; // 数据域,存放数据
ListNode* Next; // 指向下一个链表节点
}Node, *PNode;
// 链表创建函数定义
PNode CreateList(void) {
int len ; // 用于定义链表长度
int val ; // 用于存放节点数值
PNode PHead = (PNode)malloc(sizeof(Node)); // 创建分配一个头节点内存空间
//头节点相当于链表的哨兵,不存放数据,指向首节点(第一个节点)
if (PHead == NULL) // 判断是否分配成功
{
printf(“空间分配失败 \n”);
exit(-1);
}
PNode PTail = PHead; // 链表的末尾节点,初始指向头节点
PTail->Next = NULL; // 最后一个节点指针置为空
printf(“请输入节点个数:”);
scanf("%d", &len); // 输入节点个数
for (int i = 0; i < len; i++) {
PNode pNew = (PNode)malloc(sizeof(Node)); // 分配一个新节点
if (pNew == NULL) {
printf(“分配新节点失败\n”);
exit(-1);
}
printf(“请输入第 %d 个节点的数据:”, i + 1);
scanf("%d", &val); // 输入链表节点的数据
pNew->Element = val; // 把数据赋值给节点数据域
PTail->Next = pNew; // 末尾节点指针指向下一个新节点
pNew->Next = NULL; // 新节点指针指向为空
PTail = pNew; // 将新节点复制给末尾节点
}
printf(“创建链表成功\n”);
return PHead; // 返回头节点
//输出带头节点的单链表
}
void PrintLList(Node * q){
Node *p;
p=q->Next;
printf(“字符单链表结果是:\n(”);
while(p!=NULL){
printf("%d,",p->Element);
p=p->Next;
}
printf("\b)\n");
}
//取结点
Node *GetLListElem(Node * L,int i){
int j;
Node *p;
p=L;
j=0;
while((p->Next!=NULL)&&(j<i))
{
p=p->Next;
j++;
}
if(i==j)
return p;
else
return NULL;
}
// 主函数
int main(){
//PNode List = CreateList(); //创建一个指针,使其指向新创建的链表的头指针
// PrintLList(List);
int a;
PNode List;
do{
printf(“1----创建单链表\n”);
printf(“2----取结点\n”);
printf(“3----输出单链表\n”);
scanf("%d",&a);
switch(a){
case 1:
List = CreateList(); //创建一个指针,使其指向新创建的链表的头指针
break;
case 2:
printf(“选择位置:”);
int i;
scanf("%d",&i);
GetLListElem(List,i);
break;
case 3:
PrintLList(List);
break;
case 4:
a=0;
break;
}
return 0;
}while(a!=0);
return 0;
}

#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
typedef int ElementType; // 定义数据类型,可根据需要进行其他类型定义
// 链表节点的定义
typedef struct ListNode {
ElementType Element; // 数据域,存放数据
ListNode* Next; // 指向下一个链表节点
}Node, *PNode;
// 链表创建函数定义
PNode CreateList(void) {
int len ; // 用于定义链表长度
int val ; // 用于存放节点数值
PNode PHead = (PNode)malloc(sizeof(Node)); // 创建分配一个头节点内存空间
//头节点相当于链表的哨兵,不存放数据,指向首节点(第一个节点)
if (PHead == NULL) // 判断是否分配成功
{
printf("空间分配失败 \n");
exit(-1);
}
PNode PTail = PHead; // 链表的末尾节点,初始指向头节点
PTail->Next = NULL; // 最后一个节点指针置为空
printf("请输入节点个数:");
scanf("%d", &len); // 输入节点个数
for (int i = 0; i < len; i++) {
PNode pNew = (PNode)malloc(sizeof(Node)); // 分配一个新节点
if (pNew == NULL) {
printf("分配新节点失败\n");
exit(-1);
}
printf("请输入第 %d 个节点的数据:", i + 1);
scanf("%d", &val); // 输入链表节点的数据
pNew->Element = val; // 把数据赋值给节点数据域
PTail->Next = pNew; // 末尾节点指针指向下一个新节点
pNew->Next = NULL; // 新节点指针指向为空
PTail = pNew; // 将新节点复制给末尾节点
}
printf("创建链表成功\n");
return PHead; // 返回头节点
//输出带头节点的单链表
}
void PrintLList(Node * q){
Node *p;
p=q->Next;
printf("字符单链表结果是:\n");
while(p!=NULL){
printf("%d,",p->Element);
p=p->Next;
}
printf("\b)\n");
}
//取结点
Node *GetLListElem(Node * L,int i){
int j;
Node *p;
p=L;
j=0;
while((p->Next!=NULL)&&(j<i))
{
p=p->Next;
j++;
}
if(i==j)
return p;
else
    printf("找不到结点");
return NULL;
}
//求表的长度
int GetLListLength(Node *L){
    Node *p;
    int j;
    p=L->Next;
    j=0;
    while(p!=NULL){
        p=p->Next;
        j++;
    }
    return j;
}
//插入运算
int insertLList(Node *L,int i,ElementType x){
    Node *pre,*s;
    int k;
    pre=L;
    k=0;
    while(pre->Next){
        pre=pre->Next;
        k=k+1;
    }
    if(!pre)
    {
        printf("插入位置不合理!");
        return 0;
    }
    s=(Node*)malloc(sizeof(Node));
    s->Element=x;
    s->Next=pre->Next;
    pre->Next=s;
    return 1;
}
//删除运算
int DeleteLList(Node *L,int i, ElementType *e){
    Node *pre,*r;
    int k;
    pre=L;
    k=0;
    while(pre->Next!=NULL&&k<i-1){
        pre=pre->Next;
        k=k+1;
    }
    if(!(pre->Next)){
        printf("删除节点的位置不合理!");
        return -1;
    }
    r=pre->Next;
    pre->Next=pre->Next->Next;
    *e=r->Element;
    free(r);
    printf("成功删除结点!");
    return 1;
}
// 主函数
int main(){
    PNode List = CreateList(); //创建一个指针,使其指向新创建的链表的头指针
    int x,a,b;
    PrintLList(List);
    printf("选取一个结点并输出!输入结点数:");
    scanf("%d",&x);
    printf("该结点的值为:%d", *GetLListElem(List ,x));
    printf("表的长度%d", GetLListLength(List));
    printf("\n");
    printf("\n");
    printf("现在开始插入运算\n");
    printf("请输入插入的位置:");
    scanf("%d",&a);
    printf("请输入插入的元素");
    scanf("%d",&b);
    insertLList(List,a,b);
    printf("更新后的链表:\n");
    PrintLList(List);
    printf("现在开始进行删除操作!");
    printf("\n");
    printf("请输入删除的结点:");
    int xx;
    ElementType *e;
    scanf("%d",&xx);
    DeleteLList(List,xx,e);
    printf("%d",*e);
    printf("更新后的链表:\n");
    PrintLList(List);
/*int a;
PNode List;
do{
    printf("1----创建单链表\n");
    printf("2----取结点\n");
    printf("3----输出单链表\n");
    scanf("%d",&a);
switch(a){
case 1:
List = CreateList(); //创建一个指针,使其指向新创建的链表的头指针
break;
case 2:
printf("选择位置:");
int i;
scanf("%d",&i);
GetLListElem(List,i);
break;
case 3:
PrintLList(List);
break;
case 4:
a=0;
break;
}
return 0;
}while(a!=0);
return 0;*/

}

二.内核链表 内核链表是一种链表,Linux内核中的链表都是用这种形式实现的 1.特性 内核链表是一种双向循环链表,内核链表的节点节点结构中只有指针域 使用内核链表的时候,将内核链表作为一个成员放入到一个结构体中使用 我们在链表中找到内核链表结构的地址,通过这个地址就可以找到外部大结构体的地址,通过大结构体就可以访问其中的成员 优势: 内核链表突破了保存数据的限制,可以用内核链表来保存任何数据(使用一种链表表示各种类型的数据,通用性很强) 内核链表中只有指针域,维护起来更加方便,效率更高 2.使用 内核链表在内核中已经被实现,我们只需要调用其接口直接使用即可 内核链表的实现代码在内核源代码的list.h文件中 3.源代码分析 (1)节点结构: struct list_head { struct list_head *next, *prev;//前置指针 后置指针 }; (2)初始化 #define INIT_LIST_HEAD(ptr) do { \ (ptr)->next = (ptr); (ptr)->prev = (ptr); \ } while (0) (3)插入 //从头部插入 static inline void list_add(struct list_head *new, struct list_head *head)//传入要插入的节点和要插入的链表 { __list_add(new, head, head->next); } //从尾部插入 static inline void list_add_tail(struct list_head *new, struct list_head *head) { __list_add(new, head->prev, head); } (4)通过节点找到外部结构体的地址 //返回外部结构体的地址,第一个参数是节点地址,第二个参数是外部结构体的类型名,第三个参数是节点在外部结构体中的成员名 #define list_entry(ptr, type, member) ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))) (5)遍历内核链表 //遍历内核链表 #define list_for_each(pos, head) \ for (pos = (head)->next; pos != (head); \ pos = pos->next) //安全遍历内核链表 #define list_for_each_safe(pos, n, head) \ for (pos = (head)->next, n = pos->next; pos != (head); \ pos = n, n = pos->next) 二.内核链表 内核链表是一种链表,Linux内核中的链表都是用这种形式实现的 1.特性 内核链表是一种双向循环链表,内核链表的节点节点结构中只有指针域 使用内核链表的时候,将内核链表作为一个成员放入到一个结构体中使用 我们在链表中找到内核链表结构的地址,通过这个地址就可以找到外部大结构体的地址,通过大结构体就可以访问其中的成员 优势: 内核链表突破了保存数据的限制,可以用内核链表来保存任何数据(使用一种链表表示各种类型的数据,通用性很强) 内核链表中只有指针域,维护起来更加方便,效率更高 2.使用 内核链表在内核中已经被实现,我们只需要调用其接口直接使用即可 内核链表的实现代码在内核源代码的list.h文件中 3.源代码分析 (1)节点结构: struct list_head { struct list_head *next, *prev;//前置指针 后置指针 }; (2)初始化 #define INIT_LIST_HEAD(ptr) do { \ (ptr)->next = (ptr); (ptr)->prev = (ptr); \ } while (0) (3)插入 //从头部插入 static inline void list_add(struct list_head *new, struct list_head *head)//传入要插入的节点和要插入的链表 { __list_add(new, head, head->next); } //从尾部插入 static inline void list_add_tail(struct list_head *new, struct list_head *head) { __list_add(new, head->prev, head); } (4)通过节点找到外部结构体的地址 //返回外部结构体的地址,第一个参数是节点地址,第二个参数是外部结构体的类型名,第三个参数是节点在外部结构体中的成员名 #define list_entry(ptr, type, member) ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))) (5)遍历内核链表 //遍历内核链表 #define list_for_each(pos, head) \ for (pos = (head)->next; pos != (head); \ pos = pos->next) //安全遍历内核链表 #define list_for_each_safe(pos, n, head) \ for (pos = (head)->next, n = pos->next; pos != (head); \ pos = n, n = pos->next) 二.内核链表 内核链表是一种链表,Linux内核中的链表都是用这种形式实现的 1.特性 内核链表是一种双向循环链表,内核链表的节点节点结构中只有指针域 使用内核链表的时候,将内核链表作为一个成员放入到一个结构体中使用 我们在链表中找到内核链表结构的地址,通过这个地址就可以找到外部大结构体的地址,通过大结构体就可以访问其中的成员 优势: 内核链表突破了保存数据的限制,可以用内核链表来保存任何数据(使用一种链表表示各种类型的数据,通用性很强) 内核链表中只有指针域,维护起来更加方便,效率更高 2.使用 内核链表在内核中已经被实现,我们只需要调用其接口直接使用即可 内核链表的实现代码在内核源代码的list.h文件中 3.源代码分析 (1)节点结构: struct list_head { struct list_head *next, *prev;//前置指针 后置指针 }; (2)初始化 #define INIT_LIST_HEAD(ptr) do { \ (ptr)->next = (ptr); (ptr)->prev = (ptr); \ } while (0) (3)插入 //从头部插入 static inline void list_add(struct list_head *new, struct list_head *head)//传入要插入的节点和要插入的链表 { __list_add(new, head, head->next); } //从尾部插入 static inline void list_add_tail(struct list_head *new, struct list_head *head) { __list_add(new, head->prev, head); } (4)通过节点找到外部结构体的地址 //返回外部结构体的地址,第一个参数是节点地址,第二个参数是外部结构体的类型名,第三个参数是节点在外部结构体中的成员名 #define list_entry(ptr, type, member) ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))) (5)遍历内核链表 //遍历内核链表 #define list_for_each(pos, head) \ for (pos = (head)->next; pos != (head); \ pos = pos->next) //安全遍历内核链表 #define list_for_each_safe(pos, n, head) \ for (pos = (head)->next, n = pos->next; pos != (head); \ pos = n, n = pos->next) C语言下的单链表,可以增加,删除,查找,销毁节点。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值