链表学习小结

线性表是一类常用的数据结构,分为顺序表和链表

顺序表可以简单理解为数组的概念

按正常方式定义一个数组时,计算机会从内存中取出一块连续的地址来存放给定长度的数组

而链表则使由若干个结点组成

每个结点代表一个元素

而结点在内存中的存储位置通常是不连续的

struct node{

  typename data;

  node* next;

};

链表分为带头结点的点和不带头结点的点

头结点一般称为head,且数据域data不存放任何内容

而指针域next指向第一个数据域有内容的结点

1、使用malloc函数或new运算符为链表结点分配内存空间

①malloc函数

是c语言stdlib.h头文件下用于申请动态内存的函数

其函数类型是申请的同变量类型的指针

基本类型:

int *  p=(int*)malloc(sizeof(int))

这个写法的逻辑是:

以需要申请的内存空间大小(sizeof(node))为malloc函数的参数

这样malloc函数就会向内存申请一块大小为sizeof(node)的空间

并且返回指向这块空间的指针

但是这个指针此时是一个未确定类型的指针*void

因此需要强制转换(int*)

赋值等号

【申请失败】返回NULL

失败一般发生在使用malloc申请了较大的动态数组

②new运算符

c++用来申请动态空间

其返回类型同样是申请的同变量类型的指针

int* p=new int;

如果申请失败,会启动c++异常机制处理而不是返回空指针NULL

失败原因同上

2、内存泄露

指的是使用malloc与new开辟出来的内存空间在使用过后没有释放

导致其在程序结束之前始终占据该内存空间

在一些较大程序中很容易导致内存消耗过快以致最后无内存分配

①free函数

对应malloc函数(头文件stdlib.h)

free(p)

free两个效果:

a:释放指针变量p指向的内存空间

b:将指针变量p指向空地址NULL

②delete运算符

对应new

delete(p);

3、链表的基本操作

①创建链表

把每个结点的next指针指向下一个结点的地址即可

一般使用for循环来建立需要的链表

#include<utility>
#include<iostream>
#include<stdio.h>
#include<string>
#include<algorithm>
#include<map>
#include<vector>
#include<queue>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
struct node{
    int data;
    node* next;
};
node* create(int Array[])
{
    node *p,*pre,*head;
    head=new node;
    head->next=NULL;
    pre=head;
    for(int i=0;i<5;i++)
    {
        p=new node;
        p->data=Array[i];
        p->next=NULL;
        pre->next=p;
        pre=p;
    }
    return head;
}
int main()
{
    int Array[5]={5,3,6,1,2};
    node* L=create(Array);
    L=L->next;//从第一个结点开时有数据域
    while(L!=NULL)
    {
        printf("%d",L->data);
        L=L->next;
    }
    return 0;
}

②查找元素

③插入元素

void insert(head* head,int pos,int x)
{
    node* p=head;
    for(int i=0;i<pos-1;i++)
    {
        p=p->next;
    }
    node* q=new node;
    q->data=x;
    q->next=p->next;
    p->next=q;
}

④删除元素

void del(head* head,int x)
{
   node* p=head->next;
   node*pre=head;
   while(p!=NULL)
   {
       if(p->data==x)
       {
           pre->next=p->next;
           delete(p);
           p=p->next;
       }
       else
        {
            pre=p;
            p=p->next;
        }
   }
}

4、静态链表

动态链表需要指针来建立结点之间的连接关系

对有些问题来说,结点的地址都是比较小的整数

就没有必要去建立动态链表

而应该使用静态链表

静态链表的实现原理是hash

即通过建立一个结构体数组

并令数组的下标直接表示结点的地址

来达到直接访问数组中的元素就能访问结点的效果

另外

由于结点的访问非常方便

因此静态链表是不需要头结点的

struct Node{

typename data;

int next;

}node[size];

next用以存放下一个结点的地址(事实上就是数组下标)

【注意】

在使用静态链表时,尽量不要把结构体类型名和结构体变量名取成相同的名字

知识点来自于《算法笔记》

猜你喜欢

转载自blog.csdn.net/qq_42232118/article/details/82107590