数据结构之单链表

来源:互联网 发布:bbs网络论坛系统uml 编辑:程序博客网 时间:2024/06/08 13:15

首先单链表,又叫线性链表。单链表的特点是:用一组任意的存储单元存储线性表的数据元素(这组存储单元可以是连续的,也可以是不连续的)。因此,为了表示每个数据元素ai与后继ai+1的关系。用了两个域来储存,一个是数据域(存储数据元素),第二个是指针域(存储直接后继存储的位置的域)。这两个域被称为结点。


首先先看一下单链表的优缺点把:
优点是:它的插入和删除某个单链表中的元素时间复杂度较低为O(1)。
而缺点是:它的查找的时间复杂度较高为O(n)。


那就看看怎么定义线性表的把。

typedef struct LNode{    int date;//存储数据元素(数据域)    struct LNode *next;//指向下个结点的指针变量(指针域)}LNode ,*Linklist;

这里解释一下Linklist为结构体LNode的指针类型。


接着是创建一个空的单链表,并输入数据

void List(Linklist &l,int n)//创建一个空的单链表 {    int i;    Linklist p;    l=(Linklist)malloc(sizeof(LNode));//分配一个动态的内存    l->next=NULL;//头结点的指针域首先指向NULL    for(i=0;i<n;i++)    {        p=(Linklist)malloc(sizeof(LNode));//每次收入分配一个动态内存        scanf("%d",&p->date);//输入数据元素    //  printf("%d\n",p->date);        p->next=l->next;//新进链结点指向头节点所指向的地方。         l->next=p;//头节点指向链结点。    }    }

要想在单链表中插入一个数,当然就要用到插入函数了

int ListInsert(Linklist &l,int i,int e)//插入函数 {    Linklist p=l,t;//分配一个指针p,把链表的头结点赋给p,声明一个指针变量t。    int j=0;//计数器    while(p&&j<i-1)//查找    {        p=p->next;    //  printf("%d\n",p->date);         j++;    }    if(!p||j>i-1)    return 0;    t=(Linklist)malloc(sizeof(LNode));//给t分配一个动态的内存空间    t->next=p->next;//让t->next指向ai-1的指针域    p->next=t;//p->next指向t(新添加入的那个元素的结点)    t->date=e;//把插入的元素e赋值给t->date    n++;//单链表的长度增加1//  printf("n%d\n",n);    return OK;}

还有一个比较简单的删除函数,比顺序表的操作要简单许多

int ListDelete(Linklist &l,int i,int &e)//删除函数 {    Linklist p=l,q;    int j=0;    while(p->next&&j<i-1)    {        p=p->next;        j++;    }     if(!(p->next)||j>i-1)//判断该位置是否存在该单链表中    return ERROR;    q=p->next;//该删除位置的上一个位置指向的下个结点的指针域先赋给一个临时变量    p->next=q->next;//上一个位置的指针域指向删除位置的下一个结点的指针域    e=q->date;    free(q);//释放该内存空间    n--;//该单链表的长度减1    return OK;}      

#include<iostream>#include<stdio.h>#include<malloc.h>#include<stdlib.h>using namespace std;typedef struct LNode{    int date;    struct LNode *next;}LNode ,*Linklist;int n;void link(Linklist &l,int n){    int i;    Linklist p;//不能声明int p这样会出现错误,要声明Linklist型的。     l=(Linklist)malloc(sizeof(LNode));    l->next=NULL;    for(i=0;i<n;i++)    {        p=(Linklist)malloc(sizeof(LNode));        scanf("%d",&p->date);    //  printf("%d\n",p->date);        p->next=l->next;//新进链节点指向头节点所指向的地方。         l->next=p;//头节点指向链节点。    }    }int charu(Linklist &l,int i,int e){    Linklist p=l,t;    int j=0;    while(p&&j<i-1)    {        p=p->next;    //  printf("%d\n",p->date);         j++;    }    if(!p||j>i-1)    return 0;    t=(Linklist)malloc(sizeof(LNode));    t->next=p->next;    p->next=t;    t->date=e;    n=n+1;//  printf("n%d\n",n);    return 1;}int shanchu(Linklist &l,int i,int &e){    Linklist p=l,q;    int j=0;    while(p->next&&j<i-1)    {        p=p->next;        j++;    }     if(!(p->next)||j>i-1)    return 0;    q=p->next;    p->next=p->next->next;    e=q->date;    free(q);    n=n-1;    return 1;}int main(){    Linklist l,l2;    int i,e;    char c;    scanf("%d",&n);    link(l,n);    l2=l;    for(i=0;i<n;i++)    {           l=l->next;        printf("%d\n",l->date);     }    cin>>c;    l=l2;    if(c=='s')    {        scanf("%d",&i);        if(shanchu(l,i,e)==0)        printf("删除失败\n");        else         printf("已经删除%d\n",e);    }    else if(c=='c')    {        scanf("%d%d",&i,&e);        charu(l,i,e);         printf("已经插入%d\n",e);    }    else    cout<<"操作失败"<<endl;     l=l2;    for(i=0;i<n;i++)    {           l=l->next;          printf("%d\n",l->date);    }}