链表总结(一)

14 篇文章 0 订阅
7 篇文章 0 订阅

前言

    链表在组织大量数据时候效率非常高,但是操作都是使用指针进行操作,比较容易出错。因此,掌握链表的操作很重要。


测试例子及说明

    下面的例子主要实现链表节点的插入、删除链表节点、追加节点到链表、遍历链表节点。

#include <stdio.h>

#include <stdlib.h>

//定义链表节点 

struct node {

    int data;

    struct node *next;

};

//全局变量。分别表示头结点和尾节点

struct node* head;

struct node* tail;

//初始化链表头结点和尾节点

void init(){



    head = (struct node*)malloc(sizeof(struct node));

    if(!head) return -1;

    head->next = NULL;

    tail = head;

}


//获取链表的长度

int length(){

    struct node *p;
    int cnt = 0;

    for(p = head;p!=NULL;p = p->next)

        cnt++;

    return cnt;

}



//追加节点到链表

void append(int item){



    struct node* p;

    p = (struct node *)malloc(sizeof(struct node));

    if(!p) return -1;

    p ->data = item;

    p ->next = NULL;

    tail->next = p;

    tail = p;

}

//插入节点item 到i位置

int insert(int i,int item){



    struct node *q ,*ltemp;

    int j=0;



    ltemp = (struct node*)malloc(sizeof(struct node));

    if(!ltemp) exit(-1);

    q = head;

    j=1;

    while((q!=NULL) && (j<i)){

        q = q->next;

        j++;

    }

    if((!q) || (j>i)) exit(-1);

    ltemp ->next = q ->next;

    q ->next = ltemp;



    if(tail == q) tail = ltemp;



    return 0;



}

//删除i位置的节点

int del(int i){



    struct node *p, *q;

    int temp;

    q = head;

    p = head->next;

    int j=1;

    while((p!=NULL) && (i>j) ){

        q = p;

        p = p->next;

        printf("element %d \n",p->data);

        j++;

    }



    if(!p ) return -1;

    temp = p->data;

    q->next = p->next;

    if(tail == p) tail = q;

    free(p);

    return temp;

}





//遍历链表

void traversal(){

    struct node *p;

    printf("list is : ");



    for(p = head->next;p!=NULL;p=p->next){

        printf("%d ",p->data );

    }

    printf("\n");

}




//链表反转

void converse(struct node **head){



    if((*head) ==NULL || (*head)->next==NULL)

        return -1;

    struct node* p=NULL,*q=NULL;

    p = NULL;

    q =( *head)->next;

    struct node *r = q->next;



    while( r!=NULL){



        q->next = p;

        p = q;

        q = r ;

        r = q->next;

    }

    //参看下图的第四步骤就会明白

    q->next = p;

    //把q节点赋值给头指针的next

    (*head) ->next= q;


}



int main(){

    init();

    append(1);

    append(2);

    append(3);

    append(4);



    traversal();

    converse(&head);

    traversal();

    return 0;

}



    以上函数可能链表反转有点绕。因此我把思路画出来。下图步骤4的时候,while循环会终止,但是此时的q节点是孤立的还没有链接到q指向的链中。因此,在while循环外加上q-next = p; 最后再把q节点的地址赋给head节点。这样整个链都反转过来了。


链表操作注意事项总结

    1)插入节点和删除节点需要保存前置节点的指针。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
链表是一种常用的数据结构,用于存储一系列元素。C语言中,链表是通过指针来实现的,每个节点包含数据和指向下一个节点的指针。 以下是链表的基础知识总结: 1. 链表的定义: ```c struct Node { int data; struct Node* next; }; ``` 其中,data 表示节点存储的数据,next 表示指向下一个节点的指针。 2. 链表的操作: - 创建节点: ```c struct Node* createNode(int data) { struct Node* node = (struct Node*) malloc(sizeof(struct Node)); node->data = data; node->next = NULL; return node; } ``` - 插入节点: ```c void insertNode(struct Node* head, int data) { struct Node* node = createNode(data); node->next = head->next; head->next = node; } ``` 其中,head 表示链表头节点。 - 删除节点: ```c void deleteNode(struct Node* head, int data) { struct Node* p = head->next; struct Node* q = head; while (p != NULL) { if (p->data == data) { q->next = p->next; free(p); break; } q = p; p = p->next; } } ``` - 遍历链表: ```c void traverseList(struct Node* head) { struct Node* p = head->next; while (p != NULL) { printf("%d ", p->data); p = p->next; } printf("\n"); } ``` - 销毁链表: ```c void destroyList(struct Node* head) { struct Node* p = head->next; while (p != NULL) { struct Node* q = p; p = p->next; free(q); } head->next = NULL; } ``` 3. 链表的优缺点: 链表的优点是插入和删除操作的时间复杂度为 O(1),而数组的时间复杂度为 O(n)。但是,链表的缺点是无法随机访问元素,需要遍历整个链表才能找到要查找的元素。此外,链表需要额外的空间来存储指向下一个节点的指针。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值