单链表逻辑
一,单链表定义
typedef int ElemType;
typedef struct Lnode{
ElemType data;
struct Lnode *next; //指针指向下一个节点
}Lnode;
typedef Lnode *LinkList; //LinkList指向结构体,结构体占据一块连续的内存空间,所以Linklist与Lnode功能基本相同
在这儿定义了单链表的一个节点,实际上单链表的定义也就成型了。这很自然,单链表就是节点集,顺序表和单链表一开始定义的都为自己的元单位,区别仅在于存储逻辑连续与否。
单链表节点中含有数据域与指针域,数据域存储元素,指针域存储下一个元素的地址。
二,单链表初始化
bool InitList(LinkList &L)
{
L=new Lnode;
if(!L) return false;
L->next=NULL; //头节点指针域置空
return true;
}
三,单链表创建
头插法,每次把新节点放在头节点之后
void CreateList(LinkList &L)
{
int n; //首先这个链表多长得知道
L=new Lnode; //搞一个头节点
L->next=NULL;
LinkList s;
cout<<"请输入数据元素个数"<<endl;
cin>>n;
cout <<"开始创建单链表"<<endl;
cout<<"请依次输入n个元素"<<endl;
while(n--)
{
s=new Lnode; //变量存在地址中,所以用一个指针变量足矣
cin>>s->data;
s->next=L->next;
L->next=s;
}
}
尾插法创建
void CreateList(LinkList &L)
{
int n;
LinkList r,s; //r为尾指针,存在意义在于头插法每次插到头节点之后,后一个节点往哪儿插是定的,而尾插法往哪插是变的
L->next=NULL;
r=L; //尾指针初始时肯定先指向头节点
cout<<"请输入单链表长度"<<endl;
cin>>n;
cout<<"开始创建单链表"<<endl;
cout<<"请依次输入n个数"<<endl;
while(n--)
{
s=new Lnode; //开辟新节点内存空间
cin>>s->data;
r->next=s; //前一个结点指向后一个节点
s->next=NULL; //最后一个新节点肯定没有任何指向
r=s; //把尾指针指向新节点
}
}
四,取值
bool GetElem(LinkList L,int i,int &e)
{
int j; //计数器
LinkList p;
p=L->next;
j=1;
while(j<i&&p) //遍历到链表末尾或到达那个元素时跳出循环,现在还没法判断取值成功还是失败
{
p=p->next;
j++;
}
if(j>i || !p) //判断取值成功与否
return false;
e=p->data;
return true;
}
在这儿我对p指针的理解就是,结构体是块连续的内存,指针指向它,就可以调用它的属性,类似于数组
五,查找
bool LocateElem(LinkList L,int e)
{
LinkLIst p;
p=L->next;
while(p && p->data=e) //找到元素活着到达链表末尾时停止,两种情况
p=p->next;
if(!p) //判断是否是链表末尾的情况
return false;
return true; //说明找到了元素
}
六,插入
bool InsertList(LinkList &L,int i,int e)
{
int j;
LinkList p,s;
p=L;
j=0;
while(p && j<i-1) //p为空说明链表走到了末尾,j=i-1说明我们遍历到了第i-1个元素
{
p=p->next;
j++;
}
if(!p || j>i-1) return false; //j>i-1保证了i必须大于1
s=new Lnode; //与头插法原理相同
s->data=e;
s->next=p->next;
p->next=s;
}
柒,删除
bool DeleteList(LinkList &L,int i)
{
LinkList p,q;
int j;
j=0;
p=L;
while((p->next) && j<i-1) //p->next为第i-1个节点,若空,说明它是链表尾部,则输入的i非法,j<i-1也保证i>1
{
p=p->next;
j++;
}
if(!(p->next) && (j>i-1)) return false;
q=p->next; //保存被删节点的地址以备释放内存空间
p->next=q->next; //删除说白了就是把铁链中的一环拆掉,再把前面的和后面的拼起来
delete q;
return true;
}