【C语言敲重点(三)】链表的那点小操作

一、链表的动态创建(增)

(1)"头插法"动态创建链表
#include <stdio.h>
#include <malloc.h>

struct Node{
    
    
    int data;   //数据域
    struct Node *next; //指针域
};

/* 动态创建-头插法(用二级指针保存head指针的地址,就不需要返回值) */
void createLinkedList(struct Node **head,int data){
    
    
    /* 初始化新结点 */
    struct Node *newNode = (struct Node *)malloc(sizeof(struct Node));
    newNode->data = data;
    newNode->next = NULL;
    if(*head != NULL){
    
      //非第一个结点
        newNode->next = *head;  //新结点下一个指向此时的head结点
        *head = newNode;        //然后,更新head指针位置(此时新结点是head)
    }else{
    
    
        *head = newNode;
    }
}
(2)"尾插法"动态创建链表
/* 动态创建链表-尾插法(通过返回值修改(更新)head指针) */
struct Node *createLinkedList(struct Node *head,int data){
    
    
    /* 初始化新结点 */
    struct Node *newNode = (struct Node *)malloc(sizeof(struct Node));
    newNode->data = data;
    newNode->next = NULL;
    if(head != NULL){
    
     //newNode不是链表中的第一个结点
        struct Node *tail = head;
        while (tail->next != NULL){
    
     //找到尾结点
            tail = tail -> next;
        }
        tail -> next = newNode; //让尾结点的下一个指向新结点
    }else{
    
          //newNode是链表中的第一个结点
        head = newNode; //此时即是头也是尾
    }
    return head;

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

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

/* 删除链表指定元素结点 */
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;
    }
}

五、面试题(待补充)

(1)数组和链表的区别?

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

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_54429787/article/details/129468493