码迷,mamicode.com
首页 > 其他好文 > 详细

【数据结构】 链表知识点整理

时间:2018-04-11 21:40:28      阅读:325      评论:0      收藏:0      [点我收藏+]

标签:程序   span   记录   nbsp   lse   类型   参数传递   c函数   size   

首先是链表的定义:

typedef struct NODE{
    struct NODE *next;
    int value;
}Node,*Linklist;

其中 Linklist为指向Node的指针;

接下来是几个常用的函数:

一.链表的初始化:

int Linklist_init(Linklist *L)
{
*L = (Linklist)malloc(sizeof(Node));
if(!(*L))
{
printf("创建失败");
return FALSE;
}
(*L)->next = NULL;
return TRUE;
}

问:为什么需要使用Linklist *L

答: 在局部函数中进行用指针修改变量值,  如果我们想修改一个int a的值 需要传入int *a; 即指向int的指针;

同理, 我需要给一个Linklist(指向Node的指针)赋值, 就需要修改Linklist的指针。 即二级指针;

实际测试, 当写成Node *L;L = (Node *)malloc(sizeof(Node));   时不会报错, 但是L->next 并没有被正确赋值。 当试图对链表操作时系统会崩溃;(猜测是内存被分配了 却无法被指向。)

转自CSDN:

如果是使用一级参数传递,首先是main函数中定义一个Node类型的指针,这个指针用list表示,C语言在定义指针的时候也会分配一块内存,一般会占用2个字节或4个字节,现在在大部分的编译器中占用4个字节,这里用4个字节算。在这4个字节的内存中,没有任何值,所以这个指针不指向任何值。然后传递到函数init_linkedlist中,在init_linkedlist函数中,编译器首先为形参list分配一个临时指针内存块,而语句 list = (LinkedList)malloc(sizeof(Node));  中函数malloc分配一块内存,并向该程序返回一个指向这块内存的指针,这样形参list就有值了,在list所表示的临时内存区域中填入刚刚分配的内存的这块内存的地址,假设为0x10086,这样使用(*list)就可以访问这块内存(0x10086)中的内容了。此时在函数init_linkedlist中list所代表的这块内存中的内容是有值的,

但是现在的list只是占据了一个零时的内存空间,这种改变并不能反映到main函数中,init_linkedlist函数执行完了,临时的list内存块就被回收了,这样刚刚分配的内存块的地址0x10086没有被记录下来。而我们如果要初始化main函数中的链表list的话,就必须记录记录下这块内存空间(0x10086)。

然后来考虑 二级指针的情况:即 *L = (Node *)malloc(sizeof(Node));

函数的参数是一个二级指针,同样,在执行调用这个函数的时候,临时分配一个指针,这个指针占据一个占用4个字节的内存块(函数执行完要回收的),同时这个临时指针L指向主函数main中定义的list指针,这里假设主函数main中的list指针在内存中的地址为0x12306,

其中L是一块临时内存,list是主函数main的中定义的一个指针,此时list代表的内存块还没有初始化。下面执行内存分配的代码

malloc函数分配了一块内存空间,假设地址为0x10010,由于L指向list所代表的内存块,所以*L等价于list,这样将malloc函数分配的内存块赋值给*L就相当于执行语句

 这样在函数init_linkedlist中分配的一段内存也就能在main函数中反映出来了,main函数中list代表的内存块的就指向了新分配的内存,链表初始化完成。

简而言之: malloc所开辟的空间 需要通过一个钥匙(指针) 来访问;子函数的指针传递,传进去的时指针,修改的却是指针指向的内容。 同理 我们只有传进去一个指针的指针,才能修改指针的指针指向的内容(即指针)

然而我更喜欢这种写法。(return大法好——Saber是最强的)

Node* Link_init()
{
    Node *Saber;
    Saber = (Node*)malloc(sizeof(Node));
    Saber ->link = NULL;
    return Saber;
}

感觉没那么麻烦。 0.0

二. 清空链表:

int Linklist_clean(Linklist *L)
{
    Linklist p,q;
    if(!(*L)->next)
    {
        return FALSE;
    }
    p=(*L)->next;
    (*L)->next = NULL;
    while (p)
    {
        q =p->next;
        free(p);
        p=q;
    }
    printf("已经清空\n");
    return TRUE;
}

三. 销毁链表:

int Linklist_go_die(Linklist *L)
{
    Linklist p;
    while(*L)
    {
        p = *L;
        (*L) = (*L)->next;
        free(p);
    }
    printf("已经销毁\n");
    return TRUE;
}

五.查找链表中是否有整数data:

int Linklist_search(Linklist L,int data)
{
    L = L->next;
    while(L)
    {
        if(data == L->data)
        {
            return TRUE;
        }
        L=L->next;
    }
    return FALSE;
}

五.在表尾添加一个元素:

int Linklist_insert(Linklist L,int e)
{
    Linklist s;
    s = (Linklist)malloc(sizeof(Node));
    s->data = e;
    s->next = NULL;
    while(L->next)
    {
        L = L->next;
    }
    L->next = s;
    return TRUE;
}

 

六.删除链表中第i个元素:

void Linklist_free(Linklist L,int Number)
{
    Linklist Aid;
    if(Number <= 0)
    {
        printf("数据异常");
        return;
    }
    while(L&&Number)
    {
            Aid = L;
            Number--;
            L = L->next;
    }
  /*
  跳出循环有两种可能:
  1. 表到尾部而Number依然大于零。
  2. 表未到尾部, Number==0 此时Aid刚好为要删除结点的前一个结点
  */
if(Number>0) { printf("异常\n"); return; } else { Aid->next = L->next; free(L); } }

七.去除链表中重复的数据:

void Linklist_filter(Linklist *L)
{
    Linklist Aid;
    Linklist p = *L;
    Linklist_init(&Aid);
    while(p = p->next)
    {
        if(FALSE == Linklist_search(Aid,p->data))
        {
            Linklist_insert(Aid,p->data);
        }

    }
    Linklist_clean(L);
    *L = Aid;
}

 

于是写出一段程序:

创建一个链表,输入一些值, 去除其中重复的值:

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

int main()
{
    Linklist L;
    int next = 0;
    Linklist_init(&L);
    printf("输入一组数据,输入-1退出\n");
    while(next != -1)
    {
        scanf("%d",&next);
        if(next != -1)
         {
             Linklist_insert(L,next);
         }
    }
    print_Linklist(L);
    Linklist_filter(&L);
    print_Linklist(L);
    return 0;
}

 

【数据结构】 链表知识点整理

标签:程序   span   记录   nbsp   lse   类型   参数传递   c函数   size   

原文地址:https://www.cnblogs.com/tao-zhu-forever/p/8778872.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!