单链表操作
//这一次补上链表的注释,代码是空闲的时候敲出来的,如果有错,希望帮忙纠正
//部分给出了详细说明,这里只选取了基本操作,因为更复杂的链表操作太繁琐,这里就不写了
//如果有什么不懂的地方,可以随时询问
#include <iostream> using namespace std; typedef int Elemtype; struct Node { Elemtype data; Node *next; }; void Init(Node **L) //主函数里面定义Node型指针变量plist,储存单链表的头指针 { //Node *L; // L=new Node; *L=NULL; cout<<"初始化成功!\n"; } //初始化函数形参要给二级指针,相应的主函数里面实参则是对头指针的引用 void Clear_List(Node *head) //清空函数 { Node *flag; if(head==NULL) { cout<<"链表为空!\n"; return; } while(head->next!=NULL) { flag=head->next; delete(head); head=flag; } cout<<"链表已经清空!\n"; } //加一个标记,移动头指针后赋值flag保存下一个位置,然后删除当前节点 Node *Creat_list(Node *head) //赋值函数 { //int n=0; Node *p1,*p2; p1=new Node; p2=new Node; //head=NULL; cout<<"请输入链表元素,以0结束输入:"<<endl; cin>>p1->data; p1->next=NULL; while(p1->data!=0) { //n=n+1; //if(n==1) if(head==NULL) head=p1; else p2->next=p1; p2=p1; p1=new Node; cin>>p1->data; p1->next=NULL; } //cout<<head->data; return head; } //读入链表元素,在while循环里面每次将当前指针保存下来,然后不断向后更新 void List_length(Node *head) { int i=0; while(head!=NULL) { i++; head=head->next; } cout<<"链表长度length: "<<i<<endl; } void Out_list(Node *head) { // cout<<head->data; if(head==NULL) cout<<"链表为空!\n"; else { while(head!=NULL) { cout<<head->data<<" "; head=head->next; } cout<<endl; } } Elemtype Get_elem(int index,Node *head) //给定下标,求节点元素 { int j=0; //Node *p; while(head!=NULL) { j++; if(j==index) break; head=head->next; } if(j<index) { cout<<"选取的范围超出链表长度!\n"; return 0; } return head->data; } //给定的下标index,只需遍历链表,当节点数符合要求时即可 int locate_elem(Node *head,Elemtype _First) //给定节点元素,求第一个下标(也可以扩展求多个点的下标) { int n=1; while(head!=NULL) { if(head->data==_First) return n; else n++; head=head->next; } cout<<"单链表里不存在这个元素!\n"; } //同理,遍历查找出给定元素,然后直接返回下标 bool Insert_elem(Node *head,Elemtype insert_elem,int index) { Node *p,*q; if(index<1) { cout<<"输入下标有误!\n"; return false; } int i=1; while(head!=NULL) { i++; head=head->next; if(i==index-1) { p=q=new Node; q=head; //head=head->next; (*p).data=insert_elem; //这里调试了好久。。。开始我是想定义一个节点和一个指针的,输出的时候会报错 //最后还是觉得都定义指针吧,p那里不加括号的话也会报错 (*p).next=head->next; q->next=p; //p->next=head->next; //p->data=insert_elem; return true; } } return false; } //插入步骤稍微多些,要另外定义两个指针,思路就是遍历到给定下标的前一个下标,同时指针q记录下位置 //而另外一个指针p储存节点数据,并且使它指向头指针下一个点的地址,最后使q指向p即可 bool delete_Node(Node *head,int index) { int i=1; if(index<1) { cout<<"输入下标值有误!\n"; return false; } while(head!=NULL) { i++; head=head->next; if(i==index-1) { Node *p; p=new Node; p=head; head=head->next; p->next=head->next; return true; } } return false; } //操作类似于插入,不多说 bool Change_Node_Elem(Node *head,int index,Elemtype Example3) { int i=1; if(head==NULL||index<1) { cout<<"输入错误或链表为空!\n"; return false; } while(head!=NULL) { i++; head=head->next; if(i==index) { head->data=Example3; return true; } } return false; } //也是遍历链表找到给定位置,然后更新数据 int main() { //Node *plist=NULL; Node *plist; Elemtype Example1=5,Example2=7,Example3=9; cout<<"创建一个单链表(plist):\n"; Init(&plist); //初始化 plist=Creat_list(plist); //创建单链表,给单链表赋值,返回头指针 cout<<"打印原始链表:\n"; Out_list(plist); cout<<endl; cout<<"链表第三个节点的元素值为: "<<Get_elem(3,plist)<<endl; cout<<endl; //调用Get_elem函数,返回链表第三个节点内元素值 //cout<<"输出链表长度:\n"; List_length(plist); cout<<endl; cout<<"链表plist第一次出现 "<<Example1<<" 值的下标:"<<locate_elem(plist,Example1)<<endl; cout<<endl; //调用locate_elem函数,返回链表内第一个出现Example1元素的节点数 cout<<"将元素 "<<Example2<<" 插入链表第四个节点上:"<<endl; if(Insert_elem(plist,Example2,4)) cout<<"Insert is OK!\n"; else cout<<"Insert is not OK!\n"; cout<<"改变后的链表为:"<<endl; Out_list(plist); cout<<endl; cout<<"将链表第七个节点删除:"<<endl; if(delete_Node(plist,7)) cout<<"Delete is OK!\n"; else cout<<"Delete is not OK!\n"; cout<<"改变后的链表为:"<<endl; Out_list(plist); cout<<endl; cout<<"将链表plist中第三个节点的元素换成 "<<Example3<<endl; if(Change_Node_Elem(plist,3,Example3)) { cout<<"改变后的链表为:\n"; Out_list(plist); } else cout<<"数值改变失败!\n"; cout<<endl; cout<<"执行清空函数:"<<endl; Clear_List(plist); return 0; }