链表的学习
创建三个空结点,通过next的指针,将三个结点的地址串联在一起,变成一个单链表
#include <iostream> using namespace std; struct Node { int data; Node* next; }; void printList(Node* n) { while (n != NULL) { cout << n->data << " "; n = n->next; } } int main() { Node* head = new Node(); Node* second = new Node(); Node* third = new Node(); head->data = 1; head->next = second; second->data = 2; second->next = third; third->data = 3; third->next = NULL;
Node* newnode = new Node();
newnode->data = -1;
newnode->next = head;
head = newnode;
printList(head); return 0; }
补充一个知识点,在什么情况下需要传入二级指针和一级指针
1. 初始化链表头部指针需要用二级指针或者一级指针的引用。
2. 销毁链表需要用到二级指针或者一级指针的引用。
3. 插入、删除、遍历、清空结点用一级指针即可。
分析:
1. 只要是修改头指针则必须传递头指针的地址,否则传递头指针值即可(即头指针本身)。这与普通变量类似,当需要修改普通变量的值,需传递其地址,否则传递普通变量的值即可(即这个变量的拷贝)。使用二级指针,很方便就修改了传入的结点一级指针的值。 如果用一级指针,则只能通过指针修改指针所指内容,却无法修改指针的值,也就是指针所指的内存块。所以创建链表和销毁链表需要二级指针或者一级指针引用。
2. 不需要修改头指针的地方用一级指针就可以了,比如插入,删除,遍历,清空结点。假如头指针是 L,则对 L->next 及之后的结点指针只需要传递一级指针。
3. 比如一个结点 p,在函数里要修改 p 的指向就要用二级指针,如果只是修改 p 的 next 指向则用一级指针就可以了
函数中传递指针,在函数中改变指针的值,就是在改变实参中的数据信息。但是这里改变指针的值实际是指改变指针指向地址的值,因为传递指针就是把指针指向变量的地址传递过来,而不是像值传递一样只是传进来一个实参副本。所以当我们改变指针的值时,实参也改变了。
仔细看函数 InitList2(LinkList *L) 可以发现,在该函数中改变了指针的指向,也就是改变了指针自身的值。对比一下按值传递,这里的"值"是一个指针,所以我们要想指针本身的改变可以反映到实参指针上,必须使用二级指针。
这位兄弟讲的很好:彻底理解链表中为何使用二级指针或者一级指针的引用