單鏈表及其基本運算和小應用

單鏈表的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;
		}
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章