精华内容
下载资源
问答
  • 链表初始化

    千次阅读 2018-10-20 21:37:07
    typedef struct Node { int data; //数据 struct Node *next;//下一个节点的地址 }Node,*List;...//初始化,头节点已经存在 void InitList(List plist) { assert(plist != NULL); plist->next = NU...
    typedef struct Node
    {
        int data; //数据
        struct Node *next;//下一个节点的地址
    }Node,*List;//List == Node *
    
    
    
    //初始化,头节点已经存在
    void InitList(List plist)
    {
        assert(plist != NULL);
    
        plist->next = NULL;
    }
    
    
    
    
    int main()
    {
        Node head;//CreateList();
        InitList(&head);
                                //这两段是一个意思
        List p;//Node *p,这里的p自带*
        InitList(p);
       }
    

     

    展开全文
  • 我一般常用的带头结点的链表初始化

    我一般常用的不带头结点的链表初始化:

    #include <iostream>
    using namespace std;
    
    typedef struct node {
    	int data;
    	struct node* next;
    }lnode, *list;
    
    list createList()
    {
    	int data = 0;
    	cout<<"please Enter Data: (end of 0)"<<endl;
    	cin>>data;
    
    	node *p = NULL,*q;
    	list l = p;
    	
    	if( 0 != data ){
    		p = new node;
    		p->data = data;
    		p->next = NULL;
    	}else {
    		return NULL;
    	}
    	
    	l = p;
    	cout<<"please Enter Data: (end of 0)"<<endl;
    	cin>>data;
    	while ( 0 != data ){
    		q = new node;
    		q->data = data;
    		q->next = NULL;
    
    		p->next = q;
    		p = q;
    
    		cout<<"please Enter Data: (end of 0)"<<endl;
    		cin>>data;
    	}
    	return l;
    }
    
    void printList(list l)
    {
    	node *p = l;
    	while( NULL != p ) {
    		cout<<'\t'<<p->data;
    		p = p->next;
    	}
    }
    
    int main()
    {
    	printList( createList() );
    	return 0;
    }
    一直存在一个知识盲点: 

    第一、 在createList方法中,list l = p语句之后,修改p会导致指针 l 的修改,调试发现不会有这样的问题。原因在于,l 是一个指针,实际上是有独立的内存空间,汇编为证。

     

     以后对p的修改 自然而然不会影响到 l ,l 只是和p 指向了同一个node节点的内存空间,修改p,只是修改p的指向。不会影响 l 的值。

    在这段代码里的第二个容易混淆的地方。 是 createList()方法中 声明的变量 l 作用域为 createList 方法内部。 返回时会不会释放内存,导致l 的值变化。事实上 return语句返回是放在 寄存器中返回的,所有的在栈内空间 申请的局部变量内存都会被销毁,除非通过new 在堆上申请出来的内存空间。返回的指针值 l 只是通过寄存器保存了一份返回。

     

     汇编为证。多次验证,发现 都是用eax 保存返回值。 google 了下,http://blog.csdn.net/misskissc/article/details/16822349   相关内容参考这里。

    其次,在输出链表的时候需要注意:遍历链表的结束条件,是NULL  !=  p,不是 NULL  != p->next;这个地方很容易犯错,导致最后一个结点遍历不到或者出现内存溢出情况。


    其实,最上面的代码可以不那么啰嗦。

    #include <iostream>
    using namespace std;
    
    typedef struct node {
    	int data;
    	struct node* next;
    }lnode, *list;
    
    list createList(void)
    {
    	int data;
    
    	node *temp = NULL,*tail = NULL;
    	list l = temp;
    	
    	while ( 1 ){
    		cout<<"please Enter Data: (end of 0)"<<endl;
    		cin>>data;
    		
    		if( 0 == data){
    			break;
    		}
    
    		temp = new node;
    		temp->data = data;
    		temp->next = NULL;
    
    		if( NULL == l ){
    			l = temp;
    			temp = l;
    		}else {
    			tail->next = temp;
    			tail = temp;
    		}
    	}
    	return l;
    }
    
    void printList(list l)
    {
    	node *p = l;
    	while( NULL != p ) {
    		cout<<'\t'<<p->data;
    		p = p->next;
    	}
    }
    
    int main()
    {
    	printList( createList() );
    	return 0;
    }

    差别不大,但是没那么啰嗦。

    下一个议题,第二种方法,

    list createList(void)
    {
    	int data;
    
    	list l = NULL;
    	node *temp = NULL,**tail = &l;
    	
    	while ( 1 ){
    		cout<<"please Enter Data: (end of 0)"<<endl;
    		cin>>data;
    		
    		if( 0 == data){
    			break;
    		}
    
    		temp = new node;
    		temp->data = data;
    		temp->next = NULL;
    
    		*tail = temp;
    		tail = &(temp->next);
    	}
    	return l;
    }
    其实就是用二维指针。  关键是 理解 二维指针, 是指向指针的指针变量  这个概念。  通过二维指针 去操作temp节点,就不用每次都去 判断 temp 是否为空,而二维指针 在汇编层,仅仅也是把他当做一个 内存单元来处理, 相比第一个方法  是节省了一个临时变量,在操作上 每次循环节省了一个判空的操作的。


    同时  lea 与mov 指令的差别:  mov 是将 右边的地址表达式里面的值取出来,然后传到左边寄存器或内存地址(不能内存地址直接传到内存地址,必须用寄存器充当中介), 而lea 是 直接将计算出来的地址,(不取值)传到左边。 注意区别。



    看汇编码, 不管是 * 还是 &,赋值表达式最终都是 修改内存地址, 只是* 是将地址 取到寄存器中,通过 [ 寄存器 + 偏移地址 ] 寻址修改内存,而 &的操作是将内存 取到寄存器里, 从而也可以 理解&为什么不能包含在 充当左值的表达式中。

    第三种:

    list createList(void)
    {
    	int data;
    
    	list l= new node;
    	l->next = NULL;
    	l->data = (int)l;
    
    	node *temp = NULL;
    	
    	while ( 1 ){
    		cout<<"please Enter Data: (end of 0)"<<endl;
    		cin>>data;
    		
    		if( 0 == data){
    			break;
    		}
    
    		temp = new node;
    		temp->data = data;
    		temp->next = NULL;
    
    		(( node* )( l->data ))->next = temp;
    		l->data = (int)temp;
    	}
    	return l;
    }
    添加头结点,用数据域来保存当前节点的地址值  方法比较新,有学习意义。 但是会有头结点。 个人感觉,只是做法比较新颖,实际意义不大。

    以上整理自这里:   http://blog.csdn.net/chiichen/article/details/6656595  感谢。


    展开全文
  • 参考:链表初始化
    展开全文
  • 链表初始化赋值以及插入 下面展示一些 代码。 #include<iostream> #include<stdlib.h> //创建一个结构体来表示链表的结点类型 struct ListNode{ int val; struct ListNode *next; ListNode(int x):...

    链表初始化赋值以及插入

    下面展示一些 代码

    #include<iostream>
    #include<stdlib.h>
    //创建一个结构体来表示链表的结点类型 
    struct ListNode{
    	int val;
    	struct ListNode *next;
    	ListNode(int x):val(x),next(nullptr){}
    }; 
    using namespace std;
    int main(){
    	struct ListNode *head, *p, *q, *t;
    	int i, n, a;
    	//输入要存放的数据 
    	cin >> n; 
    	//头指针初始化为空
    	head = nullptr;
        for(int i = 1; i <= 8; i++){
    		//输入n个数 
    		int a=i;
    		//动态申请以个空间,用来存放一个结点,并用临时指针p指向这个结点 
    		p = new ListNode();
    		//将数据存储在当前data域中 
    		p -> val = a;
    		//设置当前结点的后继指针为空,也就是当前的下一个结点为空 
    		p -> next = nullptr;
    		if(head == nullptr){
    			//如果这是第一个创建的结点,则将头指针指向这个结点 
    			head = p;
    		}else{
    			//如果不是第一个创建的结点,则将上一个结点的后继指针指向当前结点 
    			q -> next = p;
    		}
    		//当前指针p也只向当前结点 
    		q = p;
    	} 
    	//====================== 插入操作 ======================= 
    	t = head;
    	cout << "请输入要插入的数:" << endl; 
    	cin >> a;
    	while(t != nullptr){
    		//如果当前结点的下一个结点的值大于待插入的数字,则将数插入 
    		if(t -> next -> val > a){
    			//动态申请一个空间,用来存放新增结点 
    			p = new ListNode();
    			p -> val = a;
    			//新增结点的后继指针指向当前结点的后继指针所指向的结点 
    			p -> next = t -> next;
    			//当前结的后继指针指向新增的结点 
    			t -> next = p;
    			//插入完毕,退出循环 
    			break;
    		}
    		//继续下一个结点 
    		t = t -> next;
    	}
    	
    	//输出链表中所有的数	
    	t = head;
    	while(t != nullptr){
    		cout << t -> val << " ";
    		//继续下一个结点
    		 
    		t = t -> next;
    	}
    	return 0;
    }
    
    展开全文
  • 链表初始化C++

    2021-05-13 16:10:07
    #include <iostream> using namespace std;... Node(int _data) { //显式构造函数,每次对新声明的节点类的对象进行初始化 data = _data; next = NULL; } }; //链表类 class LinkList { publi
  • 链表初始化看C语言的二级指针 博客分类: C语言 C语言链表初始化内存分配 先来看C语言创建链表、插入节点和遍历链表的一段代码: C代码 #include #include typedef int ElemType; typedef struct ...
  • 链表初始化看C语言的二级指针

    千次阅读 2014-07-26 23:35:43
    链表初始化看C语言的二级指针 博客分类: C语言 C语言链表初始化内存分配  先来看C语言创建链表、插入节点和遍历链表的一段代码: C代码   #include #include typedef int ...
  • 1、两种初始化的方法 2、逆序排列一个单向链表 //实现节点逆序 #include <stdio.h> #include<iostream> #include<stdlib.h> using namespace std; typedef struct Node { int data; struct...
  • 1.只有一个整数:a = int(input) 2.一行多个整数并用空格分开:a,b = map(int,input().split()) 3.数据较多时可用 列表存储:num = ...4.关于初始化链表: class Node: def __init__(self,x): self.val = x ...
  • 参考 《数据结构》严蔚敏 写的链表初始化,还不太好,需要修改 #include&lt;stdio.h&gt; #include&lt;stdlib.h&gt; typedef struct ListNode{ int Data; struct ListNode *next; }*L, LinkNode;...
  • 链表初始化为什么要用双重指针】 如: typedef DataType int typedef struct Node{  DataType data;  struct Node *next; }LNode,*PNode,*LinkList;   int Initial(LinkList *h){ //参数为头结点...
  • 1.前言链表是一种非常基础也非常重要的数据结构,在实际中使用非常广泛,也是各种面试里特别容易出现的类型。尤其在各大IT公司的校招中,不管笔试还是面试,链表几乎都是必出现的题型。因此不管从实际工作场景中,...
  • 链表初始化——头插法与尾插法 超详解!!! 看代码先 void CreatList(LinkNode *&L,int a[],int n) { LinkNode *s; L=(LinkNode *)malloc(sizeof(LNode)); L->next=NULL; for(int i=0;i<n;i++) { ...
  • #include<iostream> #include<stdlib.h> using namespace std;...void init(Node2 *head,int len){//初始化链表长度 Node2 *head2=head; for(int i=0;i<len;i++){//尾插法 Node2 *node=(Nod
  • 2.FREERTOS任务创建、内核链表初始化 硬件环境:cortex m4 FreeRTOS版本:v8.0.1 今天开始阅读freertos,阅读同时做下笔记,等哪天碰到移植问题再翻出来看看。 2.1 任务、链表结构体 源码中使用tskTCB来存储...
  • 链表初始化总结

    2016-02-21 13:22:00
    顺序表: 声明:structseqlist { Intlast;...初始化 seqlistinit_seqlist() { seqlistsl=malloc(sizeof(seq)); sl->last=-1;//标记位,用于判断是表头还是表尾 returnsl; } 插入操作(...
  • c语言链表初始化

    千次阅读 2016-07-20 15:07:59
    //链表的长度 int i; //循环开关 int val; //节点的值 PNODE pHead = (PNODE) malloc ( sizeof (NODE)); //造出头结点 if (NULL==pHead) { printf ( "链表动态分配失败!程序终止!\n" ); exit...
  • #C/C++链表 ##调用定义函数传参 ###引用或二级指针 //双向链表结构体 ...初始化双向链表或单链表时: //初始化双向链表 bool InitList(LinkList*& L) { L = new LinkList; if (!L) return false;
  • 剑指offer 链表初始化

    2020-02-14 22:42:47
    定义 struct ListNode { int m_nValue; ListNode* m_pNext; }; C++写法 包含值与next...链表增加函数 void AddToTail(ListNode** pHead, int value) { ListNode *pNew = new ListNode(); pNew->m_nValue =...
  • #include #include <stdlib.h>#define OK 1 #define TRUE 1 #define ERROR -1 #define FALSE -1 #define OVERFLOW -2 #define ElemType int ...//线性单链表 初始化 插入 取出 头插法 合并升序排列 //----------
  • ``` #include #include // squeue list operator #define MAXSIZE 100 typedef int Dataype; typedef struct { Dataype data[MAXSIZE]; int length; }Sqlist; // init a sqlist void Init_sqlist(Sqlist ...
  • 函数定义: #define Ok 111 #define Error -111 typedef int Status;//状态类型 ...//链表结点类型定义 typedef struct Lnode { ElemType data; struct Lnode *next; }LNode, *LinkList; Status InitLi
  • 链表初始化问题

    2012-12-30 19:53:49
    typedef struct LNode { int data; struct LNode* next; }LNode,*LinkList; int initList(LinkList* h) ...但这里我传的值LinkList h本身就是个地址的话 在initList里面做的修改不就是对地址进行操作了吗?...
  • #include<stdio.h> #include<stdlib.h> typedef int elemtype; typedef struct node{ elemtype data; struct node *next;...linklist *creatlist(linklist *L)//链表初始化 { linklist...
  • s=(LinkList)malloc(sizeof(Node)); s->data=a[i]; s->next=L->next; if(L->next!=NULL) ... 在树上有对L->next的判空语句,但是我认为在循环链表中没有NULL节点,所以我想问问这样做是否多余?

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 8,232
精华内容 3,292
关键字:

链表初始化