在学C++时接触到顺序容器 list,虽说运用不难,但不懂其实现原理,若想一探其究竟,了解其来龙去脉,链表的学习是必须的。= =若是在高校修行的本科僧,那就更有必要接触了解下了,毕竟数据结构这门课,挂科率还是挺高的(当然是对于吾等菜鸟而言)~
学习链表,我们得了解如何创建链表,如何给链表添加元素,删除元素。废话不多说,上代码。
<1>创建链表
1 typedef struct book{ 2 string name; 3 struct book* next; 4 }_List; 5 6 //创建含n个表单的链表 7 8 _List* lstCreate(int n) 9 { 10 _List* head=NULL; 11 _List* malc=NULL; 12 _List* current=NULL; 13 14 for(int i=0;i<n;++i){ 15 malc = new _List; //开辟空间,创建新表单,也可以用malloc开辟空间,malloc(sizeof(_List)) 16 malc->name="some string"; 17 malc->next=NULL; 18 if(NULL==head){ 19 head=malc; //记录链表头 20 } else{ 21 current->next=malc; //链接链表 22 } 23 current=malc; //记录当前链表 24 } 25 return head; 26 }
这段代码只要稍微画图实现,就更容易就理解了!
第一步: ------------
current = | malc |
head = | next =NULL |
------------
head, current同时指向了malc从堆中开辟_List空间,head保存当前的链表头,不在参与循环体中的复制运算
第二步: ------------
| malc(newLst) | malc再开辟空间,此次循环if()判断失败,执行else中的语句。
| next =NULL |
------------
------------
即: current->next = | malc(newLst) |
| next =NULL |
------------
而在第一步中开辟的_List已赋值给currrent,这就完成了链表的衔接了!下一步又将current定位到当前链表,current顾名思义就行了 ‘当前当前 ’。
... ... ... 第LAST步,返回链表头。链表创建完成! 恭喜恭喜 = =
**在从堆中申请空间时,加上if(NULL==malc)语句可以判断是否申请成功。
<2>打印链表
1 void lstDisplay(_List* head) 2 { 3 _List* current=head; 4 while(current!=NULL){ 5 cout<<current->name<<endl; 6 current=current->next; 7 } 8 }
我第一次实现时,将while()条件设成 current->next!=NULL;运行后发现尾巴没打印出来 = = why? 不解释。
<3>在末尾为链表添加list
1 void lstPushBack(_List* head) 2 { 3 _List* current=head; 4 while(current->next!=NULL){ 5 current=current->next; 6 } 7 current->next=new _List; 8 current->next->name="pushBack succeed!"; 9 current->next->next=NULL; //为末尾的next指针赋值为NULL,这一步骤是必须的,不然next就得迷路了,= =人称迷途指针 10 }
我无话可说= = 如果在打印链表时有搞定"why"的。 相信pushBack就水到渠成啦! 所以说,学而不思则罔,思而不学则殆 = =
<4>在链表头添加list
1 //方法1 2 3 _List* lstPushFront(_List* head) 4 { 5 _List* newHead=new _List; 6 7 newHead->name="pushFront succeed!"; 8 newHead->next=head; 9 10 return newHead; 11 }
1 //方法2 2 3 void lstPushFront(_List** head) 4 { 5 _List* newHead= new _List; 6 7 newHead->name="PushFront version 2 succeed!"; 8 newHead->next=*head; 9 *head=newHead; 10 }
这里出现的两种方法,虽说函数返回值不同,但实际上实现原理是一样的。 = = 好吧,我承认二维指针比较难理解一丢丢。
list添加最基本的搞定。后续的,在指定位置insert,想必也不是难事。