zoukankan      html  css  js  c++  java
  • 带头结点的单链表的初始化,建立,插入,查找,删除

    //带头结点的单链表的初始化,建立,插入,查找,删除
        #include <stdio.h>
        #include <stdlib.h>

        typedef int ElemType;//定义数据域类型////////////////////////  
    typedef为C语言的关键字,作用是为一种数据类型定义一个新名字。这里的数据类型包括内部数据类型(int,char等)和自定义的数据类型(struct等)。
    在编程中使用typedef目的一般有两个,一个是给变量一个易记且意义明确的新名字,另一个是简化一些比较复杂的类型声明。


    结构体中的 typedef struct Node 的意思就是,为自定义的数据类型定义一个新名字 Node。
    //定义结点类型(由数据域,指针域组成)和链表LinkList/////////////////////
        typedef struct Node
        {
          ElemType data;     //单链表的数据域
          struct Node *next;  //单链表的指针域
         }Node,*LinkedList;           
    关于结构体 struct Node *next; 这么一句代码,为什么要这么写?我写成 int *next 行不行?
    不行的。next是指向下一个Node,所以其类型必须是Node。int *next 只能指向int,而不能指向Node。所以必须定义为 Node 类型,但是 Node 是结构体,所以前面还得加上个 struct。

    //单链表的初始化/////////////////////////////////////////////////////
        LinkedList LinkedListInit()
        {
          Node *L;
          L=(Node *)malloc(sizeof(Node));  //申请结点空间
          if(L==NULL)                 //判断是否有足够的内存空间
           printf("申请内存空间失败");
           L->next=NULL;              //将next设置为NULL,初始长度为0的单链表.com
          }

    //单链表的建立1,头插法建立单链表/////////////////////////////////////
         LinkedList LinkedListCreateH()
        {
         Node *L;
         L=(Node *)malloc(sizeof(Node));   //申请头结点空间
         L->next=NULL;       //初始化一个空链表
         ElemType x;    //x为链表数据域中的数据
         while(scanf("%d",&x)!=EOF)
         {
           Node *p;
           p=(Node *)malloc(sizeof(Node));  //申请新的结点
           p->data=x;      //结点数据域赋值
           p->next=L->next;    //将结点插入到表头
           L->next=p;
          }
         return L;
        }

    //单链表的建立2,尾插法建立单链表/////////////////////////////////////
    LinkedList LinkedListCreateT()
    {
     Node *L;
     L=(Node *)malloc(sizeof(Node));    //申请头结点空间
     L->next=NULL;    //初始化一个空链表
     Node *r;
     r=L;                  //r始终指向终端结点,开始时候指向头结点
    ElemType x;                       //x为链表数据域中的数据
     while(scanf("%d",&x)!=EOF)
     {
       Node *p;
       p=(Node *)malloc(sizeof(Node));       //申请新的结点
       p->data=x;
       r->next=p ;
       r=p;
     }
     return L;
    }

    //单链表的插入,在链表的第i个位置插入x的元素
         LinkedList LinkedListInsert(LinkedList L,int i,ElemType x)
         {
           Node *pre;      //pre为前驱结点
           pre=L;
           int temi=0;
           for(temi=1;temi<i;temi++)
            pre=pre->next ;     //查找第i个位置的前驱结点
          Node *p;
          p=(Node *)malloc(sizeof(Node));
          p->data=x;
          p->next=pre->next;   
          pre->next=p;
          }
          return L;
        }

    //单链表的删除,在链表中删除值为x的元素
        LinkedList LinkedListDelete(LinkedList L,ElemType x)
        {
          Node *p ,*pre;         //pre为前驱结点,p为查找的结点;
          p=L->next;
          whiel(p-<data!=NULL)
         {
           pre=p;
          p=p->next;
        }
         pre->next=p->next;            //删除操作,将其前驱的next指向其后继
        free(p);
        return L;
        }

    ////////////////////////////////////////////////////////////
    int main()  
    {  
        LinkedList list,start;  
       printf("请输入单链表的数据:");   
        list = LinkedListCreatT();  
        for(start = list->next; start != NULL; start = start->next)  
            printf("%d ",start->data);  
        printf("/n");  
        int i;  
        ElemType x;  
        printf("请输入插入数据的位置:");  
        scanf("%d",&i);  
        printf("请输入插入数据的值:");  
        scanf("%d",&x);  
        LinkedListInsert(list,i,x);  
        for(start = list->next; start != NULL; start = start->next)  
            printf("%d ",start->data);  
        printf("/n");  
        printf("请输入要删除的元素的值:");  
        scanf("%d",&x);  
        LinkedListDelete(list,x);   
        for(start = list->next; start != NULL; start = start->next)  
            printf("%d ",start->data);  
        printf("/n");  
          
        return 0;  
    }   
     

    //题外话:
        //带头结点初始化


                Node *head;  //声明头结点
             void InitList(Node **head)
                    {
                   *head=(Node *)malloc( sizeof(Node));
                   (*head)->next=NULL;
                }
        //不带头结点初始化

        方式一:
            void InitList(Node **head){
                *head=NULL;
            }

          调用InitList(&head);

        方式二:
            void InitList(Node *head){
                head=NULL;
            }

     //带头结点的单链表,初始时一定返回的是指向头结点的地址,所以一定要用二维指针,否则将导致内存访问失败或异常。

    相关知识拓展:
     malloc()到底从哪里得到了内存空间?答案是从堆里面获得空间。也就是说函数返回的指针是指向堆里面的一块内存。操作系统中有一个记录空闲内存地址的链表。当操作系统收到程序的申请时,就会遍历该链表,然后就寻找第一个空间大于所申请空间的堆结点,然后就将该结点从空闲结点链表中删除,并将该结点的空间分配给程序。就是这样!
    什么是堆:堆是大家共有的空间,分全局堆和局部堆。全局堆就是所有没有分配的空间,局部堆就是用户分配的空间。堆在操作系统对进程 初始化的时候分配,运行过程中也可以向系统要额外的堆,但是记得用完了要还给操作系统,要不然就是内存泄漏。
    堆一般由程序员分配释放,若不释放,程序结束时可能由OS回收。注意这里说是可能,并非一定。所以我想再强调一次,记得要释放。

  • 相关阅读:
    PHP-配置方法
    正则表达式-基础使用整理
    SEO-长尾词与分词技术
    SEO-站外优化规范
    SEO-站内优化规范
    SEO-友情链接注意事项
    java netty之ServerBootstrap的启动
    [curator] Netflix Curator 使用
    Netty5.x中新增和值得注意的点
    带连接池的netty客户端核心功能实现剖解
  • 原文地址:https://www.cnblogs.com/God-boy1/p/3596532.html
Copyright © 2011-2022 走看看