数据结构:线性表之链表

前言:

线性表的存储方式除了顺序表外,还有链式存储,通过链式存储的就是链表。
链表分为单链表双链表静态链表
下面先了解一下单链表的结构体以及基本操作方式。

结构体

单链表的结构体主要包含了数据域和指针域两部分,数据域存储了当前节点的数据信息,指针域则代表下一个节点。

typedef struce LNode{
	ElemType data;
	struct LNode *next;
} LNode,*LinkList;

单链表的初始化

LNode *p;
p = (LNode *) malloc(sizeof(LNode));
p—>data = 20;
p—next = null;

删除节点P的直接后继

q = p—>next;
p->next = q-next;
free(q);

单链表的创建

  1. 头插法
LinkList creatList(LinkList head){
	head = malloc(sizeof(LNode));//初始化头节点
	LNode *node = null;//定义工作指针
	int count = 0;//记录元素个数
	head->next = null;
	node = head->next;
	scanf("%d",&count);
	for(int i=0;i<count;i++){
		node = (LNode *)malloc(sizeof(LNode));
		node->data=i;
		node->=head->next;
		head->next=node;
	}
	return head;
}

2.尾插法

LinkList createListTail(LinkList head){
	head = (LinkList) malloc(sizeof(LNode));
	LNode node = null;
	LNode end = null;
	head-next=null;
	end = head;
	int count=0
	scanf("%d",&count);
	for(int i=0;i<count;i++){
		node = malloc(sizeof(LNode));//为新节点开辟空间
		node->data=i;
		end-next=node;
		end=node;
	}
	end->next=null;
	return head;
}

3.单链表的查找

bool getElem_L(LinkList *L,int i,ElemType &e){
	LNode *P;
	p = L->next;
	int j=1;
	while(p && j<i){
	p = p->next;
	++j;
	}
	if(!p || j>i){
		return false;
	}
	e = p->data;
	return true;
}

大致思路:循环遍历找到下标的指定节点。循环结束的标致为p为空或者j>=i。
4.单链表的按值查找

LNode *LocateNode(LNode *L,int key){
    LNode *p = L-next;//定义工作指针
    while(p!=null && p->data!=key){
    	p = p->next;
    }
    if(p!=null && p->data==key){
    	return p;
    }else{
    	return false;
    }
}

5.单链表的插入操作
在带头节点的单链表L第i个位置插入元素e;

bool ListInsert(LinkList *L,int i,ElemType e){
	LNode *p=L;//这里工作指针从头节点开始而不是从第一个数据节点开始,因为有可能插入的位置就是在头节点之后
	int j=0;
	while(p&& j<i-1){
	p = p->next;
	j++
	}	
	if(!p || j>i-1){
		return false;
	}
	LNode *s;
	s = malloc(sizeof(LNode));
	s->data =e;
	s->next = p->next;
	p->next = s;
	return true;
}
6.单链表的删除操作
bool delete(Linklist *L,ElemType e){
	LNode *p,LNode *q;
	p=L;
	int j=0;
	while(p && j<i-1){
		p=p->next;
		j++;
	}
	if(!p->next || i-1){
		q = p->next;
		p->next = p->next;
		e = q->data;
		free(q);
	}	
}
7. 按值删除
```c
void deleteByValue(){
	LNode *p=L,*q = L->next;
	while(q !=null && q->next !=key){
	//定义两个指针,一个指向删除节点,一个指向被删除节点的前驱
	    p=q; q = q->next;
}
if(q->data==key){
	p->next = q->next;
	free(q);
}else{
	return false;
}
	}

8.将La 和Lb两个有序链表合并成一个有序链表
//合并以La,Lb为头节点两个有序链表

LNode * mergeList(LNode *la,LNode *b){
	//合并以La,Lb 为头节点的两个有序链表
	LNode *pc,*pa,*pb,*ptr;
	Lc = La,pc = pa;pa=La->next;pb=Lb->next;
	while(pa!=null && pb!=null){
		while( pa->data < pb->data){
			pc->next = pa;
			pc = pa;
			pa = pa->next;
		}
		if(p->data > p->data){
			pc = next=pb;
			pc = pb;
			pb = pb->next;
		}
		if(pa->data==pb->data){
			pc->next = pa;
			pc = pa;
			pa = pa->next;
			ptr = pb;
			pb = pb->next;
			free(ptr;);
		}
	}
	if(pa!=null){
	pc->next = pa;
	}
	if(pb!=null){
	pc->next = pb;
	}
}

9.删除链表中的重复元素

void deleteRepeat(LNode *L){
	LNode *p = L->next,*q,*ptr;
	while(p!=null){
		q = p; ptr=p->next; //p 为工作指针,q则为被删除元素的直接前驱,ptr则为被删除元素的指针
		while(ptr!=null){
			if(ptr->data == p->data){
				q->next = ptr->next;
				ptr=q->next;
				free(ptr);
			}else{
				q = ptr;
				ptr = ptr->next;
			}
		}	
		p = p->next;
	}
}

10.将链表实现逆序(采用头插法)

LNode * revertList(LNode *head){
	if(null == head->next){
		return head;
	}
	LNode p = head->next;
	head->next=null;
	while(p){
		tmp = p->next;
		p->next = head->next;
		head->next = p;
		p=tmp;
	}
	retrun head;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值