C语言--链表

链表概念

链表特点

(1)n个节点离散分配

(2)每一个节点之间通过指针相连

(3)每一个节点有一个前驱节点和一个后继节点

(4)首节点没有前驱节点,尾节点没有后继节点

struct link{
       int data;          //定义数据域
       struct link *next; //定义指针域,存储直接后继的节点信息
};

链表定义

#include <stdio.h>
#include <stdlib.h>
struct  Test
{
    int a;
    struct Test * next;
};
void printlink(struct Test * point)
{
    while(point!=NULL){
        printf("%d ",point->a);
        point=point->next;
        
    }
    putchar('\n');

}

int main()
{   
    struct Test *head=NULL;
    struct Test t1={1,NULL};
    struct Test t2={2,NULL};
    struct Test t3={3,NULL};
    struct Test t4={4,NULL};
    head = &t1;
    t1.next=&t2;
    t2.next=&t3;
    t3.next=&t4;
    printlink(head);
    system("pause");
    return 0;
}

数组和链表的区别?

数组和链表都属于线性表,数组的存储方式是顺序存储,它在内存中占用的地址空间是连续的,定义出来后空间大小是固定的,虽然读取效率较高但是不利于扩展(想要实现插入数据,修改数据相较于链表困难);链表的存储方式是链式结构,每一个结点的地址空间可以不连续,通过指针连接,每一个结点保存下一个结点的地址,相比于数组扩展方便,操作数据也更容易。

链表动态创建(增)

头插法

void insertfromhead(struct stu **head,struct stu *new)
{
    if(*head == NULL){
        *head = new;
    }else{
        new->next = *head;
        *head = new;
    }
}
或者
struct Test *insertFromHead(struct Test*head,struct Test *new)
{
    if(head == NULL){
        head = new;
    }else{
        new->next=head;
        head=new;
    }
    return head;
}

用头插法动态创建链表

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

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


void insertfromhead(struct stu **head,struct stu *new)
{
    if(*head == NULL){
        *head = new;
    }else{
        new->next = *head;
        *head = new;
    }
}

void createLink(struct stu **head)
{
    struct stu *new;
    while(1){
        new = (struct stu*)malloc(sizeof(struct stu));
        printf("输入数据,(0代表结束):\n");
        scanf("%d",&(new->data));
        new->next = NULL;
        
        if(new->data == 0){
            return;
        }
        insertfromhead(head,new);
    }
}

void printfLink(struct stu *head)
{
    struct stu *p = head;
    while(p != NULL){
        printf("%d ",p->data);
        p = p->next;
    }
    putchar('\n');
}

int main()
{
    struct stu *head = NULL;
    createLink(&head);
    printfLink(head);
    
    return 0;
}

尾插法

void insertfromtail(struct stu *head,struct stu *new)
{
    if(head == NULL){
        head = new;
    }
    while(head->next != NULL)
    {
        head = head->next;
    }
    head->next = new;
}

或者
struct Test *insertFromTail(struct Test*head,struct Test *new)
{   
    struct Test *p=head;
    if(p==NULL){
        head=new;
        return head;
    }
    while(p->next!=NULL){
        p=p->next;
    }
    p->next=new;
    return head;
}

尾插法动态创建链表

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

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


void insertfromtail(struct stu **head,struct stu *new)
{
    if((*head) == NULL){
        (*head) = new;
    }
    while((*head)->next != NULL)
    {
        (*head) = (*head)->next;
    }
    (*head)->next = new;
}

void createLink(struct stu **head)
{
    struct stu *new;
    while(1){
        new = (struct stu*)malloc(sizeof(struct stu));
        printf("输入数据,(0代表结束):\n");
        scanf("%d",&(new->data));
        new->next = NULL;
        
        if(new->data == 0){
            return;
        }
        insertfromtail(head,new);
    }
}

void printfLink(struct stu *head)
{
    struct stu *p = head;
    while(p != NULL){
        printf("%d ",p->data);
        p = p->next;
    }
    putchar('\n');
}

int main()
{
    struct stu *head = NULL;
    createLink(&head);
    printfLink(head);
    
    return 0;
}

删除链表的某个结点(删)

删除结点分两种情况:①是删除头结点;②是中间结点(包括尾结点)

/* 删除链表指定元素结点 */
struct Node *deleteNode(struct Node *head,int data){
    struct Node *ptmp = head;
    if(ptmp->data == data){     //删除头结点:直接让下一个结点成为头,并释放原来的head
        head = ptmp -> next;
        free(ptmp);
    }else{  //删除中间结点:判断下一个结点,让此时的head指向next的next即可
        while ( ptmp != NULL){
            if( ptmp->next->data == data){  //特别注意:这里查询到了指定的data后,要return
                struct Node *p = ptmp->next;    //否则出现段错误:原因是下一个可能为NULL
                ptmp->next = ptmp->next->next;
                free(p);
                return head;
            }
            ptmp = ptmp -> next;
        }
    }
    return head;
}

修改链表的某个结点(改)

/* 修改指定元素 */
struct Node *updateNode(struct Node *head,int data,int newData){
    struct Node *ptmp = head;
    while(ptmp != NULL){
        if(ptmp->data == data){
            ptmp->data = newData;
        }
        ptmp = ptmp -> next;
    }
    return head;
}

链表的遍历(查)

/* 遍历 */
void traverLinkedList(struct Node *head){
    struct Node *ptmp = head;
    while(ptmp != NULL){
        printf("%d ",ptmp->data);
        ptmp = ptmp -> next;
    }
}

如果要改变链表里的数据--就得传链表的地址

如果要改变链表头的地址-就得传链条头地址的地址

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值