一些注意点
- 链表的引用型为List *&La 不用引用型是 List *La
- 顺序表引用型为List &La 不用引用型是 List La
Tips:用* &a时,如果链表a指向的节点地址本身不变,则用* a即可,比如插入时,只对a后面的节点插入,而a指针指向的节点不变,用* a即可。
如果顺序表用&a,如果是添加删除都必须用&a,因为顺序表是数组形式,改变其中一个,也使得顺序表改变。 如果这样写:
java typedef struct LNode
{
ElemType data;
struct LNode *next;
}LNode,*LinkList;
- void fun(LinkList &La,LinkList La)**等价于** - void fun(Node *&La,Node *La)(引用型,非引用型)
- C语言中参数的传递分为值传递和指针传递,而C++中多了一个引用传递。值传递和指针传递都不可以改变传递进来的值,但指针可以改变其所指向的值。在C语言中,调用函数时传入的参数叫做“实参”,而在函数声明或定义中在函数头中的参数叫做“形参”。值传递与指针传递中,形参的改变是不影响实参的。C++中,引用传递,形参与实参实际上是同一个内容的不同名字,因而形参的变化会改变实参。引用传递是C++中一个很重要也很方便的特性,比如在可能会产生不必要的复制时,采用引用传递是一个很不错的解决方案。
上述代码有些函数头中变量类型与变量之间有个&,这个表示该变量是引用类型的,是C++特性。在C语言中存在值传递与指针传递,值传递中形参不可以改变实参的值,需要通过指针来修改。而引用变量实际上就是实参的另一个名字,这种类型的形参改变会影响实参的值。
循环链表全部遍历的结束条件需要注意,不是非空,而是判断是否到头结点了
- 双向链表的重要之处在于插入和删除时的操作顺序,切勿弄乱顺序而丢失数据。
- LNode L;//声明链表要带号
- 双向循环链表p->next==head表示走到尾节点
写法 《数据结构高分笔记》建议用 方法一
- 方法一
typedef struct LNode { ElemType data; struct LNode *next; }LNode; LNode *List;
- 方法二
typedef struct LNode { ElemType data; struct LNode *next; }LNode,*LinkList; LinkList List; 与LNode *Node; List与Node是一样的
- 方法三
struct LNode { ElemType data; struct LNode *next; }; typedef struct LNode *LinkList;
- while(q!=L)// 如果q=L 则是循环链表循环完一遍链表了
while(q!=NULL) 普通链表写法
-
- 记住一定要写q=q->next,忘记写会造成程序死循环,已经两次没有写了….
void printDLNode(DLNode *L)
{
DLNode *q;
q=L->next;
int i=0;
while(q!=L)// 如果q=L 则是循环完一遍链表了
{
if(i++)//good idea!
{
putchar(' ');
}
printf("%d",q->data);
q=q->next;
}
printf("\n");
}
- 不建立新节点,使链表L倒序 Tips
void reverseList(LNode *&L)//头插即可反转
{
LNode *q,*s;
q=L->next;//必须指向L的下一个节点,否则下一步L->next=NULL会让q变成空表
L->next=NULL;
while(q!=NULL)
{
s=q->next;//一定要放在第一句,不能放在倒数第二句,因为头插之后,q的位置发生了变化,s不是指向期望的值
q->next=L->next;
L->next=q;
//s=q->next;
q=s;
}
}
- 每申请一个节点,记得将B->next设置为空
B=(LNode *)malloc(sizeof(LNode)); B->next=NULL;