您的位置:首页 > 其它

单链表的建立、插入、删除、遍历

2014-07-16 17:24 323 查看
首先建立结构体Linklist以及全局指针head作为表头,具体不在赘述,除此之外本次只详细描述尾插法,头插法不再述说。

创建

声明一结点q和计数器变量i;

初始化一空链表p;

让p的头结点的指针指向NULL,即建立一个带头结点的单链表;

循环实现后继结点的赋值和插入。

尾插法代码如下:

Linklist *Create()
{
Linklist *p,*q;
head = NULL;
while(i--)
{
p = new Linklist;   //分配内存空间
p->data =           //对p中数据进行赋值操作
if(head=NULL)
head=p;     //head为空,使头指针指向节点p
else
q->next = p;		//把新节点添加到表尾
q = p;				//把指针指向新节点
}
if(head!=NULL)
q->next=NULL;  		//尾节点的指针域置空
}


插入

单链表第i个数据插入结点的算法思路:

声明一结点p指向链表头结点,初始化j从1开始;

当j<1时,就遍历链表,让p的指针向后移动,不断指向下一结点,j累加1;

若到链表末尾p为空,则说明第i个元素不存在;

否则查找成功,在系统中生成一个空结点s;

将数据元素e赋值给s->data;

单链表的插入刚才两个标准语句;s->next = p->next;p->next = s;

返回成功。

代码如下:

Linklist pHead;//链表

int insert(Linklist* pNode)
{
Linklist *p,*q;

//第一种情况,链表为空
if(pHead = NULL)
{
pHead=node;
return;
}
//第二种情况,pNode节点num值小于等于链表头结点的num值(num 链表判定值)
if(pNode->num<=pHead->num)
{
pNode->next=pHead;

pHead=pNode;//将pNode插入到pHead前面成为链表头

return;
}
//第三种情况,循环查找正确位置
p=pHead;
q=pHead->next;
while(q!=NULL)
{
if(pNode->num>q->num)//判断pNode节点的num是否(大于)当前节点num,具体问题具体分析
{
p=q;
q=q->next;//不断后移进行查找
}
else
break;
}
//将pNde节点插入正确的位置
p->next=pNode;
pNode->next=q;
}


删除

单链表第i个数据删除结点的算法思路:

声明结点p指向链表第一个结点,初始化j=1;

当j<1时,就遍历链表,让P的指针向后移动,不断指向下一个结点,j累加1;

若到链表末尾p为空,则说明第i个元素不存在;

否则查找成功,将欲删除结点p->next赋值给q;

单链表的删除标准语句p->next = q->next;

将q结点中的数据赋值给e,作为返回;

释放q结点。

可以这样:p->next = p->next->next;

也可以是:q=p->next; p->next=q->next;

代码如下:

Linklist pHead;//链表

void del(int num)
{
Linklist *p,*q;

//第一种情况,链表为空
if(pHead = NULL)
return;
//第二种情况,删除链表头
p=pHead;
if(p->num==num)
{
pHead=p->next;

delete p;

return;
}
//第三种情况,循环查找删除位置
q=p->next;
while(q!=NULL)
{
if(q->num==num)
{
p->next=q->next;
delete p;
return;
}
if(q->num>num)
return;
p=q;
q=q->next;
}
}


遍历

获得链表i个数据的算法思路:

声明一个结点p指向链表第一个结点,初始化j从1开始;

当j<i时,就遍历链表,让p的指针向后移动,不断指向一下结点,j+1;

直到链表末尾p为空,输出每个位置的数据元素。

代码如下:

Linklist pHead;//链表

void print()
{
Linklist *p=pHead;

while(p!=NULL)
{
p=p->next;
cout<<        //输出相应数据
}
}


另附上一个完整的代码:

#include <stdio.h>
#include <stdlib.h>

//定义结构体类型struct node
struct node{
int  data;
struct node *next;
};

//用typedef定义结构体类型Lnode、结构指针类型LinkList
typedef struct node Lnode, *LinkList;

//函数原型声明
void  Build(LinkList head); //建立带头结点的单链表head
void Disp(LinkList head);   //输出带头结点的单链表head
int Del(LinkList head,int x); //删除单链表head中元素值为x的结点
void Insert(LinkList head,int x);  //在单链表head(该单链表按元素值升序)中插入新元素x
void FreeLink(LinkList head);  //彻底释放单链表

int main()
{
LinkList head; //声明指向头结点的指针变量head
int x;

//初始化单链表:申请头结点
head=(LinkList)malloc(sizeof(Lnode));
head->next=NULL; //head->next为空,表示该链表为空

//建立单链表head
Build(head);

//顺序输出单链表
Disp(head);

//删除单链表head中元素值为x的结点
printf("输入被删除的元素:\n");
scanf("%d",&x);
if( !Del(head,x) ) //若找到,删除,返回1,若找不到,返回0
printf("该元素不存在\n");
Disp(head);

//在单链表head中插入新元素x, 使单链表依然保持升
printf("输入新元素值:\n");
scanf("%d",&x);
Insert(head,x);
Disp(head);

//彻底释放单链表
FreeLink(head);

return 0;
}
void  Build(LinkList head)
{

int d;
LinkList s, rear;

//rear指向head. rear总是指向表尾结点,初始时链表为空,rear执行head
rear=head;

//当读入数据不是-1,就建立新节点链入链表尾部
printf("升序输入若干整数,输入-1表示输入结束\n");
while(scanf("%d",&d),d!=-1)
{
//为当前整数建立结点s;
s=(LinkList)malloc(sizeof(Lnode));
s->data=d; //将d存入s的data域
s->next=NULL; //s的后继为NULL

//将当前结点链入链表尾,做p的next
rear->next=s;

//rear指向新的表尾结点s
rear=s;
}
}

void Disp(LinkList head)
{
LinkList p;

//这是带头结点的单链表,p指向首元素结点head->next
p=head->next;

//当p值非空
while(p)
{
printf("%d\n",p->data); //输出当前结点的data
p=p->next; //p指向后继结点
}
}

//若找到,删除,返回1,若找不到,返回-1
int Del(LinkList head,int x)
{
//若要删除某一结点,需获取其前驱结点,故,使用两个指针,cur指向被删除结点, pre指向其前驱结点
LinkList pre,cur;

//带头结点的单链表,pre指向头结点,cur指向首元素结点
pre =head;
cur=head->next;

//查找值为x的结点,若x存在,循环结束时, cur指向值为x的结点,pre指向其前驱
while(cur && cur->data!=x)  //当cur非空 且 当前元素不是x,pre和cur均指向下一个结点
{
pre=cur;
cur=cur->next;
}

//若找不到值为x的元素,返回0
if(cur==NULL)
return 0;

//删除cur所指结点
pre->next=cur->next;
free (cur);
return 1;
}

//彻底释放单链表
void FreeLink(LinkList head)
{
LinkList cur, temp;

cur=head; //pre指向头结点
while(cur)
{
temp=cur->next; //将当前结点cur的后继指针暂存入temp中
free(cur); // 释放当前结点
cur=temp; //cur指向下一个结点
}
}

//在单链表head(该单链表按元素值升序)中,插入新元素x
void Insert(LinkList head,int x)
{
// 要在pre和cur之间插入新节点
LinkList pre, cur, s;

//带头结点的单链表,pre指向头结点,cur指向首元素结点
pre =head;
cur=head->next;

//构造新节点s
s=(LinkList)malloc(sizeof(Lnode));
s->data=x; //将x存入s的data域
s->next=NULL; //s的后继为NULL

//寻找新结点插入位置
while(cur && cur->data < x)  //当cur非空 且 当前元素比x小,pre和cur均后移一个结点
{
pre=cur;
cur=cur->next;
}

//在在pre和cur之间插入新节点s
s->next=cur;
pre->next=s;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐