单链表及其基本运算和小应用

十年热恋 提交于 2020-03-12 02:34:43
单链表的c语言定义
typedef struct Node {
	ElemType data;/*数据域*/
	struct Node *next;/*指针域*/
} Node,*LinkLIst;/*给node起两个别名,这两个别名等效*/
LinkLIst L;/*L为单链表的头指针,也称为单链表L*/

LinkList 与 Node*同为结构指针类斜体样式型,这两种类型是等价的。

通常我们习惯上用LinkList说明指针变量,强调它是某个单链表的头指针变量,用
Node*来定义指向单链表中节点的指针。

单链表的基本运算
一、求带头节点单链表的长度
int listlength(linklist L){
	node *p;
	p=->next;
	j=0;/*用来存放单链表的长度*/
	while(p!=NULL){
		p=p->next;
		j++;
	}
	return j;
} 
二、建表
1.建立空表
InitList(linklist *L)/*建立空表*/{
	L=(linklist)malloc(sizeof(node));
	L->next=NULL;
} 
2.头插法建表
linklist creatfromhead(linklist l){
	node *s;
	char c;
	int flag=1;/*设置一个标志,初值为1,当输入“$”时,flag为0,建表结束*/
	while(flag){
		c=getchar();
		if(c!='$'){
			s(node*)malloc(sizeof(node))
			/*申请新结点s*/
			s->data=c;
			s->next=L->next;
			/*将结点s头插入链表L*/
			L->next=s; 
		}
		else flag=0;
	}
}
3.尾插法建表
linklist createfromtail(linklist L){
	linklist L;
	node *r,*s;
	int flag=1;/*设置一个标志,初值为1,当输入“$”时,flag为0,建表结束*/
	r=L;/*r指针始终动态指向链表的当前表尾,以便做尾插入,其初值指向头结点*/
	while(flag){
		c=getchar();
		if(c!='$'){
			s=(node*)malloc(sizeof(node));
			s->data=c;
			r->next=s;
			r=s;/*r就是当前尾结点*/
		} 
		else{
			flag=0;
			r->next=NULL;/*将最后一个结点的next链域置为空,表示链表结束*/
		}
	}
} 
三、查找
1.按序号查找
node *get(linklist L,int i)
/*在带头结点的单链表L中查找第i个结点,
若找到(1<=i<=n),则返回该结点的存储位置,否则返回NULL*/
{
	int j=0;/*计数器*/
	node *p;
	p=L;/*从头结点开始扫描*/
	while((p->next!=NULL)&&(j<i)){
		p=p->next;/*扫描下一结点*/
		j++;/*已扫描结点计数器*/
	}
	if(i==j)return p;/*找到了第i个点*/
	else return NULL;/*找不到,i<=0或i>n*/	
} 
2.按值查找
node *locate(linklist L,elemtype key)
/*在带头结点的单链表L中查找其结点值等于key的结点,
若是找到则返回该结点的位置p,否则返回NULL*/
{
	node *p;
	p=->next;/*从表中第一个结点比较*/
	while(p!=NULL){
		if(p->data!=key)
		p=p->next;
		else break;/*找到结点key退出循环*/
	} 
	return p; 
}
四、单链表插入
void inslist(linklist L,int i,elemtype e){
	node *pre,*s;
	int k=0;
	pre=L;
	while(pre!=NULL&&k<(i-1))
	/*在第i个元素之前插入,则先找到第i-1个数据元素的存储位置
	使pre指针指向它*/
	{
		pre=pre->next;
		k++; 
	}
	if(!pre)/*如果当前位置pre为空,表示已找完但还未数到第i个
	说明插入位置不合理*/
	{
		printf("插入位置不合理");
		return ERROR; 
	}
	s=(node*)malloc(sizeof(node));
	/*为s申请一个新结点并由s指向它*/
	s->data=e;
	/*将待插入结点的值e赋给s的数据域*/
	s->next=pre->next;/*完成插入操作*/
	pre->next=s;
	return OK; 
} 
五、单链表删除
void dellist(linklist L,int i,elemtype *e)
/*在带头结点的单链表L中删除第i个元素,
并将删除的元素保存到变量*e中。*/
{
	node *p,*r;
	int k=0;
	p=L;
	while(p->next!=NULL&&k<(i-1))
	/*寻找被删除结点i的前驱结点i-1使p指向它*/
	{
		p=p->next;
		k++; 
	}
	if(k!=i-1)
	/*即循环是因为p->next=NULL而跳出来的*/
	{
		printf("删除位置i不合理");
		return ; 
	}
	r=p->next;
	p->next=p->next->next;
	*e=r->data;
	free(r);/*释放被删除结点所占内存空间*/
} 
算法应用示例
求两个集合的差
void difference(linklist la,linklist lb) {
	node *pre,*p,*q,*r;
	pre=la;
	p=la->next;
	while(p!=NULL) { /*逐个确定A表一个元素*/
		q=lb->next;/*查是否属于b表*/
		while(q!=NULL&&q->data!=p->data) {
			q=q>next;
		}
		if(q!=NULL) {
			r=p;
			pre->next=p->next;
			p=p->next;
			free(r);
		} else {
			pre=p;
			p=p->next;
		}
	}
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!