可能因为之前没有很认真学习指针的知识,导致我在学习链表的时候磕了很久,终于搞懂了一点,并学会了自己写单链表的创建、查找、插入、删除和遍历(虽然目前还只是在浅层学习,但是依然很开心!!)
下面逐段介绍并讲解代码,希望能给迷茫中的小伙伴一些感觉和思路。
结构体链表的定义:
typedef struct node //定义一个结构体(结点)
{
int data; //数据域
struct node* next; //指针域
}node,*LinkList; //node*相当于LinkList
typedef定义了两种类型,结构体类型node(用于表示结点)和结构体指针类型LinkList(用于表示链表头指针),node*等于LinkList,均可以视为结构体的别名。
建立头指针(设立头结点,方便后续的遍历和一系列操作)
void InitList(LinkList &L)
{
L=(LinkList)malloc(sizeof(node)); //为头结点开辟内存空间
L->next=NULL; //将L的指针域置为NULL(指向NULL),表示后续还无结点
}
由于上面说到node*等于LinkList,开辟内存空间时此处的L=(LinkList)malloc(sizeof(node));中的LinkList可换为node*,因为二者相同(均为结构体别名),即空间内存大小相同。
插入结点(头插法):
void createList(LinkList &L,int a)
{
node *s;
s=(node*)malloc(sizeof(node)); //定义一个新结点并为之开辟内存空间
s->data=a; //将数据赋值到结点的数据域
s->next=L->next; //将此时L的指针赋给s的指针
L->next=s; //让L指向s
}
第一个结点s插入时L的指针为NULL,即L->next=NULL;进行s->next=L->next时就是把s的指针置为空(s->next=NULL),再将L指向s(L->next=s);第二个结点插入时循环上述步骤,只不过L此时指向第一个结点。
在目标位置查找元素:
void findNode(LinkList &L,int pos)
{
int i=1;
int goal; //待插入的数值
node *p=L->next; //定义一个新指针p指向L的下一个结点
while(i<pos&&p)
{
p=p->next; //将此时p的下一个结点(也是L->next->next)赋给p。即将p指针往下移动
i++;
}
if(!p)
{
cout<<"error"<<endl;
}
else
{
goal=p->data;
cout<<goal<<endl;
}
}
在指定位置插入新结点(跟头插法的元素插入相似):
void insertNode(LinkList &L,int pos,int c)
{
node *p=L; //将头指针L赋给p,此时L和p指向头结点
node *insertNode; //定义待插入的新结点
insertNode=(node*)malloc(sizeof(node)); //为新结点开辟内存空间
int i=1;
while(i<pos&&p)
{
p=p->next; //让p指向的下一个结点成为新的p
i++;
}
if(!p)
{
cout<<"error"<<endl;
}
else
{
insertNode->data=c;
insertNode->next=p->next; //将待插入结点的指针 指向 p指向的下一个结点
p->next=insertNode; //改变p的指向,让p指向待插入的结点的地址
}
}
删除结点:
void deleteNode(LinkList &L,int pos)
{
node *p=L; //使p和L指向头结点
node *goalNode; //要删除的目标结点
int i=1;
while(i<pos&&p)
{
p=p->next; //使p指向的下一个结点成为新的p,让p不断沿链表深入
i++;
}
if(!p)
{
cout<<"error"<<endl;
}
else
{
goalNode=p->next; //寻找目标结点,此时的目标结点为p指向的下一个结点
p->next=p->next->next; //直接让p指向的结点,成为此时p指向的结点 的 下一个结点
free (goalNode); //释放结点内存空间
}
}
遍历结点:
void showList(LinkList &L)
{
LinkList p=L; //让p和L都指向头结点
while(p!=NULL)
{
p=p->next; //使p指向的下一个结点成为新的p,让链表一直往下遍历
cout<<p->data<<" "; //输出元素
}
}
最后就是写主函数啦。写链表的时候,要注意指针的指向和操作的简易性,努力磕一磕,争取自己拿下来!
如有错误之处,欢迎各位指出。