单链表就是一种特殊的结构体组合而成的数据结构,想要学好C语言链表操作必不可少。
定义一个单链表:
typedef struct LinkNode
{
int data; //数据域
LinkNode * next; //指针域
}*LinkList;
初始化链表:
void initLink(LinkList &l) // 链表初始化
{
l=new LinkNode; //开辟一个储存空间
l->next=NULL; //头指针指向空
}
输出链表:
void showLink(LinkList l)
{
LinkList p=l; // p指向头节点
cout<<"the linklist:";
while(p->next!=NULL)
{
cout<<p->next->data<<"->"; //输出节点数据(增加的数据都是放在头结点后面,头结点中无数据)
p=p->next; //移动指针
}
cout<<"^"<<endl;
}
创建一个单链表。其实链表创建有很多种方式,但是都大同小异。我们主要介绍两种,头插法和尾插法。
创建新节点:
//创建新结点
LinkList createNode(int x)
{
LinkList p=new LinkNode;
//输入新结点的值
p->data=x;
p->next=NULL;
return p;
}
头插法:
void headCreate(LinkList &l,LinkList p)
{
p->next=l->next;
l->next=p;
}
尾插法:
使用尾插法不同的点就是我们需要先找到尾指针!!!
void rearCreate(LinkList &l,LinkList p)
{
LinkList rear=l;
while(rear->next!=NULL)rear=rear->next;//定位尾指针rear
rear->next=p;
}
查找操作:
查找数据域中的值然后进行比较
LinkList findNode(LinkList l,int x)
{
LinkList p=l;//把p指向l的头指针
while(p->next!=NULL)
{
if(p->next->data==x)return p;//如果数据相同返回指针
else p=p->next;//否则不断的移动头指针
}
cout<<x<<"NOT FOUND!"<<endl;
return NULL;
}
删除操作:
//删除:在单链表删除x结点
bool delNode(LinkList &l,int x)
{
LinkList p=findNode(l,x);//p是待删除结点的前趋结点,先找到需要删除的节点
if(p==NULL)return false;
p->next=p->next->next; //删除节点其实就是将p指向的指针向后移动一位,被删除的那个指针的指向可以不用管生存周期会让他自行消失。
return true;
}
插入操作:
其实插入操作就是首先得找到要插入节点的前驱节点。原理图和头结点差不多
//插入:在x结点之前插入新的结点nn
bool insertNode(LinkList &l,LinkList nn,int x)
{
LinkList p=findNode(l,x);//p是待插入结点x的前趋结点
if(p==NULL)return false;
nn->next=p->next;//将新的指针指向p->next,然后将p->next指向新的指针
p->next=nn;
return true;
}
如果看不懂的各位请看完整的程序流程:
#include <iostream>
using namespace std;
typedef struct LinkNode
{
int data;
LinkNode * next;
}*LinkList;
//初始化
void initLink(LinkList &l)
{
l=new LinkNode;
l->next=NULL;
}
//输出链表
void showLink(LinkList l)
{
LinkList p=l;
cout<<"the linklist:";
while(p->next!=NULL)
{
cout<<p->next->data<<"->";
p=p->next;
}
cout<<"^"<<endl;
}
//创建新结点
LinkList createNode(int x)
{
LinkList p=new LinkNode;
//输入新结点的值
p->data=x;
p->next=NULL;
return p;
}
//创建单链表:头插法
void headCreate(LinkList &l,LinkList p)
{
p->next=l->next;
l->next=p;
}
//创建单链表:尾插法
void rearCreate(LinkList &l,LinkList p)
{
LinkList rear=l;
while(rear->next!=NULL)rear=rear->next;//定位尾指针rear
rear->next=p;
}
//查找:在单链表中查找某个符合条件的结点前趋结点
LinkList findNode(LinkList l,int x)
{
LinkList p=l;
while(p->next!=NULL)
{
if(p->next->data==x)return p;
else p=p->next;
}
cout<<x<<"NOT FOUND!"<<endl;
return NULL;
}
//删除:在单链表删除x结点
bool delNode(LinkList &l,int x)
{
LinkList p=findNode(l,x);//p是待删除结点的前趋结点
if(p==NULL)return false;
p->next=p->next->next;
return true;
}
//插入:在x结点之前插入新的结点nn
bool insertNode(LinkList &l,LinkList nn,int x)
{
LinkList p=findNode(l,x);//p是待插入结点x的前趋结点
if(p==NULL)return false;
nn->next=p->next;
p->next=nn;
return true;
}
//*******************主函数*********************************
void main()
{
LinkList linklist;
initLink(linklist);//初始化
//showLink(linklist);//输出链表
LinkList p;
//用头插法
/* for(int i=1;i<=5;i++)
{
p=createNode(i);//新建结点
headCreate(linklist,p);//将p结点头插法插入到单链表中
}
*/
//用尾插法将结点插入到单链表中
for(int i=1;i<=5;i++)
{
int x;
cout<<"input the data of the new node:";
cin>>x;
p=createNode(x);//新建结点
rearCreate(linklist,p);//将p结点头插法插入到单链表中
}
showLink(linklist);//输出链表
//查找结点
p=findNode(linklist,99);
if(p!=NULL)cout<<p->next->data<<" found."<<endl;
//删除单链表中的99结点
delNode(linklist,99);
showLink(linklist);
//生成新结点999
LinkList nn=createNode(999);
//将nn插入到结点99之前
insertNode(linklist,nn,30);
showLink(linklist);//显示单链表
}
最后如果各位对C语言感兴趣的话,可以私聊我,小编这里有一套完整的C语言基础资料可以免费分享给大家,希望大家在C语言的道路上越走越远!!!!