C语言基础之链表

  •  链表介绍

  1. c语言的单向链表翻转是面试官常问问题之一;
  2. 链表和数组一样都是存储数据,链表是非连续,非顺序的存储结构;
  3. 链表是灵活的内存动态管理(随机分配空间),删除创建结点非常方便;
  4. 链表组成:由一系列结点组成;
  5. 链表结点:实际上是结构体变量。
typedef struct _LINKNODE
{
int data;                 // 数据域
struct _LINKNODE *next;   // 指针域
}Link_Node;
  • 链表结点包含两个部分:
  • 1.存储数据元素的数据域(结构体),
  • 2.存储下一个结点地址的指针域.
  • 链表和数组的区别

  1. 数组:一次性分配连续的存储区域,int num[60] = {0};
  2. 优点:随机访问元素效率高
  • 缺点:
  1. l开辟内存过大时,易分配失败
  2. l插入和删除元素效率低下
  3. 链表:无需一次性分配连续的存储空间,只需要分配n快结点存储区域,通过指针建立联系
  • 优点:
  1. 不需要一次性分配连续的存储区域
  2. l删除和插入效率高
  3. 缺点:
  4. 随机访问元素效率低
  • 链表分类

  •  静态链表和动态链表

  1. 链表按照线性表链式存储结构分为静态链表和动态链表
  2. 静态链表:是在初始化的时候分配好足够的内存空间,存储空间是静态的,分配在栈上,模拟数组实现的,是顺序的存储结构
  3. 动态链表:是动态申请内存的,每个节点物理地址不连续
  • ​​​​​​​实现代码

#ifndef __LINK_LIST_H
#define __LINK_LIST_H 
#define TAIL  //#define HEAD 采用头插法创建链表,#define TAIL 采用尾插法创建链表
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
typedef struct Link_List 
{
    int                 data;
    struct Link_List    *next;
}L_list;

L_list * create_list(L_list * L, int data);
L_list * delete_data(L_list* L, int pose);
L_list * insert_data(L_list* L, int pose, int data);  
void foreach(L_list * L);

#endif /* end of ifndef __LINK_LIST_H  */

int main(int argc, char *argv[])
{
    L_list * L1;
    L_list * L2;
    L_list * L3;
    int data;
    L2 = create_list(L1, data);        //创建链表
    L3 = insert_data(L2, 3, 50);       //按位插入元素
    puts("Before delete:");
    foreach(L3);                      //遍历链表
    L3 = delete_data(L3, 3);        //按位删除元素
    puts("After delete:");
    foreach(L3);  

    return 0;
}/* end of main */


#ifndef HEAD              
L_list * create_list(L_list * L, int data)  //#define HEAD 采用尾插法创建链表
{
    puts("Head insert:");
    L_list * head; 
    head  = malloc(sizeof(L_list));
    head ->data = 20;
    head ->next = NULL;
    L = head;
    for (data = 20; data <30;data++)
    {
        L_list * newNode = malloc(sizeof(L_list));
        L -> next = newNode;
        L = newNode;
        newNode -> data = data;
        newNode -> next =NULL;

    }

    return head;

}
#endif /* end of define HEAD*/

#ifndef TAIL     
L_list * create_list(L_list * L, int data) //#define TAIL 采用头插法创建链表
{
    puts("Tail insert:");

    L_list * tail;
    L  = malloc(sizeof(L_list));
    tail = L;
    L ->data = 20;
    L ->next = NULL;
    for (data = 20; data < 30 ;data++)
    {
        L_list * newNode = malloc(sizeof(L_list));
        if (L ->next == NULL)
        {
            L -> next = newNode;
            tail = newNode;
            tail -> data = data;
            tail -> next = NULL;
        }
        else 
        {
            newNode ->next = tail;
            L->next = newNode;
            newNode -> data = data;
            tail = newNode;
        }
    }

    return L;
}
#endif /* end of define TAIL */

void foreach(L_list * L)    //遍历链表
{
    if (NULL == L)
    {
        return ;
    }
    while (NULL != L->next)
    {
        L = L->next;
        printf("%d\n", L->data);
    }

}

L_list * insert_data(L_list* L, int pose, int data)  //按位插入元素
{
    if (NULL == L || pose < 0)
    {
        return;
    }

    int   i = 0;
    L_list* tmp;
    L_list* l;
    l= L;
    tmp = L;
    
    for ( i = 0; i<pose; i++)
    {

        tmp = l->next;
        l = l->next;
    }
    L_list * newNode = malloc(sizeof(L_list)); 
    newNode ->data = data;
    newNode -> next = tmp ->next->next;
    tmp ->next = newNode;

    return L;
}

L_list * delete_data(L_list* L, int pose)  //按位删除元素
{ 
    if (NULL == L || pose < 0)
    {
        return;    
    }

    L_list*    tmp;
    L_list*    l;
    l= L;
    tmp = L;
    int        i = 0;
    for (i = 0; i< pose; i++)
    {
        tmp = l->next;
        l = l->next;
    }
    tmp = tmp ->next;
    l->next = tmp -> next;
    free(tmp);
    return L;

}

​​​​​​​

发布了16 篇原创文章 · 获赞 9 · 访问量 794

猜你喜欢

转载自blog.csdn.net/qq_44045338/article/details/104639561