链表的建立及遍历:
分为如下几步:
声明链表这种结构,比如:

点击查看代码
typedef struct node* listlink;     //定义一个指针类型名称,使指针变量能像其他变量那样声明,而不需要在每个指针变量前加*
typedef struct nude(){
     int data;
     struct listlink next;}LNode;  //声明该结构的一个变量,叫LNode

在int main 外创建一个链表并且初始化it,比如:

点击查看代码
Linklist ListInit(){   //首先是他的指针变量,然后是他的名字
   listlink list;       //先定义一个指针,名字叫list,或者说,声明一个指向节点的指针,叫list
   list = new LNode();  //给指针分配一块内存块的地址
   list->data = 0;      //代表被指针指向的节点的数据为0,这个节点的地址域为空,这个链表现在只有一个头节点
   list->next = NULL;
   return list;        //因为这个是在int main 外的一个函数,因此要有返回值,并且返回值是那个头指针
}

设定一个函数,然后通过这个函数扩充链表,比如:

点击查看代码
void Insertlist(int n, Linklist list){
    Linklist p;       //首先建立了一个指针p
    int a[n];         //然后创建了一个数组,这个数组是用来保存东西的,具体作用就是先把要装进链表的数储存在数组里
    int i = 0;
    cin>>n;
    for(i;i<n;i++){
      cin>>a[i];}
   
    Linklist p = list;//对的,上一步还没完,仅仅是把数装进数组并没有体现出链表的优势,于是上一步建立的p登场了,他先指向了头节点,然后随着一个for循环,一个一个的建立出小小的动态内存空间,也就是节点们,p也随之缓缓移动,一个一个的指向新建立的节点们,然后把数组里的值赋给当下所指的节点,并将他们节点的地址域通通连接上,此时,p是一位优秀的传信使者
    for(int i =0;i<n;i++){
       p->next = new LNode();
       p->data = a[i];}
       if(i = n-1){         //最后,不要忘记了一个重要的判断,如果p指向的下一个节点的地址域为空,也就是说,数组里的数已经全部被移进了链表里,于是,p所指的下一个节点应该为空
            p->next = NULL;}
       else{
            p = p->next;}  //要不然的话,就继续指向下一个
   }

下面是链表遍历:

点击查看代码
void ListTraver(Linklist list){  //这是定义这个函数的过程
      Linklist p;                //新定义了一个追踪指针,先让这个指针指向头节点
      p = list;
     
        if(p->next != NULL){    //然后让这个指针p从头节点list开始,一个一个敲门问里面存的啥,顺着地址门牌,并把他们输出
           cout<<p->data<<' ';}
        else{                  //直到问到尽头
           p = p->next;
         } 
          cout<<p->data;       //但是有一个问题出现了,就是当p移动到最后一个节点时,也就是当最后一个节点指向NULL,他就不输出最后一个节点的值了
                              //所以需要最后一个输出将最后一个节点的值输出来
                            } 

全代码:

点击查看代码
#include<bits/stdc++.h>
#include<stdio.h>
using namespace std;

typedef int ElemType;

typedef struct node{
   int data;
   struct node *next;
} LNode;

typedef struct node *Linklist;


Linklist ListInit(){
   Linklist list;
   list = new LNode();

   list->data = 0;
   list->next = NULL;
   return list;
}

void InsertList(int n,Linklist list){
   ElemType a[n];
   int i;
   for(i = 0;i<n;i++){               //出错点:i= 0;一定要放到括号内
    cin>>a[i];
   }


   Linklist p = list;
   for(i=0;i<n;i++){
    p->data = a[i];
    p->next = new LNode();          //插入的时候不要忘记建立一个新节点

     if(i==n-1){
        p->next = NULL;
     }
     else {
        p = p->next;
     }
   }
}

void ListTraver(Linklist list){
   Linklist p = list;
   while (p->next != NULL){
       cout<<(p->data)<<' ';
       p = p->next;
   }
   cout<<(p->data);
}
int main(){         
   int n; 
   cin>>n;
   if(n<=0){
    return 0;
   }

   Linklist list;         //这个语句的意思是搞了一个叫list的指针变量
   list = ListInit();     //ListInit函数的意思是建立一个头节点并叫list
   InsertList(n,list);    //因为这个函数搞了一个容纳n个数的数组,并在头节点之后扩充
   ListTraver(list);        //遍历的是头节点叫list的链表
   return 0;

}

节点和指针的关系:
我们知道,节点包括数据域和地址域,这个地址域,是与这一个节点相连的下一个节点的地址,他其实就是一个指针,就像是一个路牌

点击查看代码
//譬如在这一块代码中
 Linklist p = list;    //含义为,新建的一个叫p的节点,让他和头节点list是一个东西
   for(i=0;i<n;i++){   //然后在扩充节点的过程中,新建一个又一个的p,让老p的指针的路牌写上新p的地址
    p->data = a[i];
    p->next = new LNode();
   if(i==n-1){
        p->next = NULL;
     }
     else {
        p = p->next;  //执行这一句,就是将老p和新p连接起来
     }
   }
}
posted on 2024-04-03 21:55  fafrkvit  阅读(1)  评论(2编辑  收藏  举报