CPP随笔——链表初识1
本人学到Cpp链表的时候啊,那是肥肠的激动,难道我这么快就可以在Cpp里面玩到列表了吗,然后我就意识到了这东西虽然原理看起来简单,但做起来还真不是这样。
今天我们先来复现一下整形列表(其实实现灵活列表的话,可以把结构的数据设计为一个void指针和一个记录数据类型的整形,比如规定1是整形,2是long,3是...)
先不管存储数据的方式,今天的重点是尝试复现列表的创建、连接、扩展、反向
我先写一个头部为空的链表
我们先把头文件、结构和函数定义这些准备工作做上
#include链表1-0——准备工作using namespace std; struct List { int data; List *pN; }; List *create(int*,int); void show_list(List*); void add_to_end(List*,List*); void append(List*,int*,int len); void reverse(List*);
然后开始一个个写程序
List *create(int *data,int len) { List *res; res = new List; *res={0,NULL}; append(res,data,len); return res; }链表1-1——create
voidshow_list(List*head){head=head->pN;if(head){cout<链表1-2——打印链表data<<"\t";if(head->pN){show_list(head);}}}
void add_to_end(List* head,List* new_list) { if(head->pN) { add_to_end(head->pN,new_list); } else { head->pN=new_list->pN; } }链表1-3——将new_list拼接到list后面
void appendone(List* head,int data) { List *new_list,*new_head; new_list=new List;//一定要分配新的栈空间 ,不然新的结构的pN指针就会指向自身 new_head=new List; *new_head={0,new_list}; *new_list={data,NULL}; add_to_end(head,new_head); }链表1-4——append
void append(List* head,int *data,int len) { for(int i=0;i链表1-5——加入一系列数) { appendone(head,data[i]); } }
void reverse(List *head) { List *new_head,*pt,*pc,*pp; pc=head->pN; pt=NULL; pp=NULL; while(pc) { pt=pc->pN; pc->pN=pp; pp=pc; pc=pt; } *head={0,pp}; }链表1-6——链表反转
然后我们可以尝试运行一下
int main(){ int ar[4]={1,2,3,4}; List* l=create(ar,4); reverse(l); show_list(l); }链表1——实战
接下来我创建一个没有空表头的链表
#include链表2-1——创建using namespace std; struct Lnode { double data; Lnode* next; }; void ShowList(Lnode* head) { if(head){ cout < data <<endl; if(head->next) ShowList(head->next); //递归调用 } }
void AddToEnd(Lnode* pnew, Lnode*& head) { if(!head) { head=pnew; pnew->next=NULL; } else AddToEnd(pnew, head->next); //递归调用 }链表2-2-1——addtoend的递归实现
void AddToEnd(Lnode* pnew,Lnode*& head)//此处一定不能省略&,*&代表引用指针 { if(!head){ head=pnew; cout<endl; } else{ Lnode *p; for(p=head;p->next;p=p->next); p->next=pnew; } cout<"\t"<<endl; pnew->next=NULL; }链表2-2-2——addtoend的非递归调用
Lnode* GetNode() { Lnode* item = new Lnode; item->next=NULL; item->data=0.0; return item; }链表2-3——创建节点
int main() { Lnode* head=NULL; Lnode* temp; double d; cout <<"Data? "; cin >>d; while(d>0&&(temp=GetNode())) { temp->data=d; AddToEnd(temp, head); cout <<"Data? "; cout<"\t"<<endl; cin >>d; } cout<"\t"<<endl; ShowList(head); }链表2——实战
我们可以看到2-2中我们用了指针引用
因为没有空表头的情况下, 我们的可能会更改这个链表的指针(从NULL改为pnew)
链表1-1中的创建函数也可以这么写:
void create(int *data,int len,List*&l) { l = new List; *l={0,NULL}; append(l,data,len); }链表1-1-1——创建,引用
那么主函数的更改如下:
int main(){ int ar[4]={1,2,3,4}; List* l; create(ar,4,l); reverse(l); show_list(l); }链表1——实战2.0