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

首先建立结构体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;

}


  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值