zoukankan      html  css  js  c++  java
  • 数据结构之链表

    一、定义--离散存储【链表】

    n个节点离散分配;彼此通过指针相连;每个节点只有一个前驱节点,
    每个节点只有一个后续节点;首节点没有前驱节点,尾节点没有后续节点。

    二、专业术语:

    首节点:第一个有效节点
    尾节点:最后一个有效节点
    头节点:第一个有效节点前面的那个节点;头节点不存放有效数据;
    加上头节点是为了方便对链表的操作
    头指针:指向头节点的指针变量
    尾指针:指向尾节点的指针变量

    三、分类:单链表;双链表;循环链表;非循环链表

    四、代码

    #include<stdio.h> 
    #include<malloc.h> 
    #include<stdlib.h> 
    
    typedef struct node{
        int data; //数据域 
        struct node * pNext; //指针域 
    }NODE,* PNODE;  //NODE等价于struct node;PNODE等价于 struct node * 
    
    PNODE init_link(void);
    void traverse_link(PNODE pHead);
    bool is_empty(PNODE pHead);
    int length_link(PNODE pHead);
    bool insert_link(PNODE pHead,int pos,int val);
    bool del_link(PNODE pHead,int pos,int * val);
    bool sort_link(PNODE pHead);
    
    int main(void)
    {
        //首先创建头节点
        PNODE pHead = NULL;  //一个指针只需一个参数,即头节点即可确定下来。 
        int val;
        int * pVal = &val;  //用来接收删除的节点数据 
        
        pHead = init_link();
        
        if(is_empty(pHead))
        {
            printf("数组为空。。。
    ");
        }else{
            
            printf("数组不为空。。。
    ");
        }
        printf("数组长度为:%d
    ",length_link(pHead)); 
        
        traverse_link(pHead);
        
        insert_link(pHead,3,333);
        traverse_link(pHead);
        
        if(del_link(pHead,4,pVal))
        {
            printf("链表节点删除成功,你删除的节点数据是:%d 。
    ",*pVal);
        }else{
            printf("链表节点删除失败!");
        }
    
        
        
        sort_link(pHead);
        traverse_link(pHead);
        
        
         
        return 0;
    }
    
    PNODE init_link(void)
    {
        int i;
        int len;  //链表有效长度 
        int val;  //临时存放用户数据 
        
        printf("请输入链表有效长度:len= ");
        scanf("%d",&len);
        
        PNODE pHead = (PNODE)malloc(sizeof(NODE));
        if(pHead == NULL)
        {
            printf("内存分配失败,程序终止
    ");
            exit(-1);
        }
        PNODE pTail = pHead;  //设置一个尾指针,永远指向尾节点,方便新节点pNew挂在后面 
        pTail->pNext = NULL;
        
         
        
        for(i=0;i<len;i++)
        {
            printf("请输入第 %d 个节点的值:",i+1);
            scanf("%d",&val);
            
            PNODE pNew = (PNODE)malloc(sizeof(NODE));
            if(pNew == NULL)
            {
                printf("内存分配失败,程序终止
    ");
                exit(-1);
            }
            
            pNew->data = val;
            pTail->pNext = pNew;
            pNew->pNext = NULL;
            pTail = pNew;
        }
        return pHead;
        
    }
    void traverse_link(PNODE pHead)
    {
        PNODE p = pHead->pNext;  //第一个有效节点 
        while(p!=NULL)
        {
            printf("%d  ",p->data);
            p = p->pNext; 
            
        }
        printf("
    ");
    }
    
    bool is_empty(PNODE pHead)
    {
        PNODE p = pHead->pNext;
        if(p==NULL)
            return true;
        else
            return false;
    } 
    
    int length_link(PNODE pHead)
    {
        int cnt=0;
        PNODE p = pHead->pNext;
        while(p!=NULL)
        {
            cnt++;
            p = p->pNext;
        }
        return cnt;
    }
    bool insert_link(PNODE pHead,int pos,int val)
    {
        int i=0;
        PNODE p = pHead;
        
        while(p!=NULL && i<pos-1)
        {
            p = p->pNext;
            i++;
        }
        if(p==NULL || i>pos-1)
            return false;
        PNODE pNew = (PNODE)malloc(sizeof(NODE));
        if(pNew==NULL)
        {
            printf("动态内存分配失败!
    ");
            exit(-1);
        } 
        pNew->data = val;
        PNODE q = p->pNext;
        p->pNext = pNew;
        pNew->pNext = q;
        return true; 
    }
    bool del_link(PNODE pHead,int pos,int * pVal)
    {
        int i=0;
        PNODE p = pHead;
        
        while(p->pNext!=NULL && i<pos-1)
        {
            p = p->pNext;
            i++;
        }  //经过while循环,p此时指向pos位置前面那个节点 
        if(p->pNext==NULL || i>pos-1)
            return false;
        
        PNODE q = p->pNext; //q即为pos位置处的节点 
        *pVal = q->data;
        //删除pos位置的节点 
        p->pNext = p->pNext->pNext;
        free(q);  //释放内存,防止内存泄漏。 
        q = NULL;
        return true;
    }
    
    /*
    何为算法:
            狭义的算法是与数据的存储方式密切相关的;
            广义的算法是与数据的存储方式无关的;
        泛型:
            利用某种技术达到的效果就是:针对不同的存储方式,执行的操作是一样的
    */
    bool sort_link(PNODE pHead)
    {
        int i,j,temp;  //数组中定义的参量 
        PNODE p,q;  //链表中定义的参量 
        
        for(i=0,p = pHead->pNext;i<length_link(pHead)-1;i++,p=p->pNext)
            for(j=i+1,q=p->pNext;j<length_link(pHead);j++,q=q->pNext)
                if(p->data<q->data)         //等价于a[i]<a[j]
                {
                    temp = q->data;        //等价于a[i] = a[j];
                    q->data = p->data;    //a[j] = a[i];
                    p->data = temp;        //a[i] = temp;
                }
        
    }

    运行结果:

    五、数组与链表优缺点对比

    数组(元素类型相同,大小相等):
    优点:存取速度很快;
    缺点:插入删除速度很慢;空间通常有限制;事先需要知道数组长度;需要大块内存块

    链表:

    优点;空间没有限制;插入删除元素很快
    缺点:存取速度慢

  • 相关阅读:
    性能测试监控指标-数据库
    cpu 故障定位
    ubuntu安装boost
    固定IP下虚拟机网卡配置及ssh
    零基础天池新闻推荐初学-04-排序模型+模型融合的简单学习(TODO 待进一步完善)
    零基础天池新闻推荐初学-04-特征工程(制作特征列和标签列,转为监督学习)
    零基础天池新闻推荐初学-03-多路召回
    零基础天池新闻推荐初学-02-数据分析
    零基础天池新闻推荐初学-01-赛题理解&Baseline
    初学推荐系统-06- GBDT+LR模型
  • 原文地址:https://www.cnblogs.com/ljd4you/p/9507241.html
Copyright © 2011-2022 走看看