数据结构-(无头结点)单链表的基本操作实现----------随笔记录(3)

操作代码如下:

#include  
#include 

typedef int ElemType;

//----------------不含头结点单链表--------------- 
 
//定义单链表结构 
typedef struct LNode{     //声明节点的类型和指向结点的指针类型 
	ElemType data;        //数据域 
	struct LNode *next;   //指针域 
}LNode,*LinkList;         //重命名为 LNode LinkList为指向LNode的指针类型 

//1.初始化,创建头结点 
bool InitList(LinkList &L){

	L=NULL; 
	return true;
}

//2.无头结点单链表的遍历 
void LinkList_Printf(LinkList L){
	int count=0;      //定义一个计数器,计算单链表的长度 
	printf("单链表成员有:") ; 
	while(L!=NULL){   
		printf("  %d  ",L->data); 
		L=L->next;   
		count++;      
	}
	printf("\n");
	printf("表中共有: %d 个元素\n",count) ;
}

//3.采用头插法创建单链表
LinkList List_HeadInsert(LinkList &L){
    InitList(L) ;    
    LNode *s;  
    ElemType x;    
    printf("请输入数据(输入9999为停止):\n");  
    scanf("%d",&x);     
    while(x!=9999){           
        s=(LNode *)malloc(sizeof(LNode));     
        s->data=x;                          
        s->next=L;              
        L=s;                        
        scanf("%d",&x);              
    }
    return L;            //返回一个表
}
			
//4.采用尾插法创建单链表
LinkList List_TailINsert(LinkList &L){  //正向建立单链表 
	LNode *s,*r;   //s为新插入的结点;r为尾指针 
	ElemType x;        
	printf("请输入数据(输入9999为停止):\n");  
	scanf("%d",&x);
	if(x!=9999){
		L = (LinkList)malloc(sizeof(LNode));
		L->data = x;
		r = L;
		scanf("%d",&x);
		while(x!=9999){
			s=(LNode *)malloc(sizeof(LNode));  //创建新的结点s并自动分配内存空间 
			s->data=x;    //s指针数据域赋值为x 
			r->next=s;
			r=s;
			scanf("%d",&x);
		}
	}
	r->next=NULL;//尾指针指向空 
	return L;  //发挥一个表 
} 

 //5.求表的长度
int Length_List(LinkList L){
	int len=0;
	LNode *p=L;
	if(L==NULL){
		return len;
	}
	else{
		len++;
	}
	while(p!=NULL){
		len++;
		p=p->next;
	}
	return len;
}

//6.1按位查找,返回第i个元素(带头结点)的元素值 如果不调用求表长长度函数 
 LNode *GetElem_1(LinkList L,int i)
 {
 	if(i<0 || i>Length_List(L)){   
 	
 		printf("查询的i不合法");
 		
	 }
	LNode *p=L; //新建一个指针p指向头结点 
	int j=1;  //定义一个计数器 
	while(p!=NULL&&jnext;  //p指向下一个结点 
	}
	return p;
 }
 
 //6.2按位查找,返回第i个元素(带头结点)的元素值 调用求表长长度函数 
 LNode *GetElem_2(LinkList L,int i)
 {		
 	LNode *p=L;
 	if(i<0 || i>Length_List(L)){   
 	
 		printf("查询的i不合法");
 		
	 }

	for(int j=1;jnext;  //p指向下一个结点 
	}
	return p;
 }
 

 
//------------------- 查询操作----------------------------------------------------------------- 
//7-1.按值查找 ,如果查询到e并返回所在的位置i 

int LocateElem_1(LinkList L,ElemType e){
	int L_length=Length_List(L); //调用求表长度函数,求出表长 L_length
	LNode *p=L;  
	//从第一个结点开始查询 
	int j=1;  //定义一个计数器 
	while(p!=NULL&&p->data!=e){   
		p=p->next;      
		j++;
	}
	if(j>L_length) {   
		return 0;
	}else{
		return j; 
	}
} 

//7-2.按值查找 ,如果查询到e并返回所在的地址 

LNode *LocateElem_2(LinkList L,ElemType e){
	
	LNode *p=L;  
	//从第一个结点开始查询 
	while(p!=NULL&&p->data!=e){  //查询e的值是否与表中的元素相等 ,直到   相等  或  查询结束 停止循环 
		p=p->next;      
	}
	if(p) {         //当p不为空时 即查询到e对应的结点 
		return p;  //若找到e返回结点p 
	}else{
		return 0;  //如果表中不存在所查数据e,则返回0 
	}
} 

//--------------------------插入操作-----------------------------------------------
 
//8. 后插操作:p结点后插入指定结点e 
bool InsertNextNode(LNode *p,ElemType e){
	
	if(p==NULL){ 
		return false;
	}
	
	LNode *s=(LNode *)malloc(sizeof(LNode));//定义一个新结点s,作为插入的结点
	 
	if(s==NULL){
		return false;
	}
	
	s->data=e;      //把e赋值给结点s的数据域 
	s->next=p->next; //结点s插入到p结点指向的下一个结点之前 
	p->next=s;   //把结点s插入到p结点之后 
	return true;
}
  

//9. 按位序插入--将元素e插入表L第i个位置 
bool  ListInsert_L(LinkList &L,int i,ElemType e){
	int length=Length_List(L) ;
	if(i<1||i>length){  //若i不合法,返回false 
		return false;
	}
	
	if(i==1){//插入第一个结点的操作与其它结点不同
	 	LNode *s=(LNode *)malloc(sizeof(LNode));
	 	s->data=e;
		s->next=L;
		L=s;
		return true; 
	} 
	
 	LNode *p=GetElem_1(L,i-1);   //即可以直接调用上面的GetElem函数 	
 	
	return InsertNextNode(p,e);//后插操作: 下面的操作可以封装为InsertNextNode(p,e); 
}

  

//----------------删除----------------- 

//10.删除表L第i个位置的元素,用e返回被删除的元素的值 
bool  ListDelete_L(LinkList &L,int i,ElemType &e){
	int length=Length_List(L) ;
	if(i<1||i>length){  //若i不合法,返回false 
		return false;
	}
	
	LNode *p=GetElem_1(L,i-1); //调用GetElem函数查询第i-1个结点 
	
	//如果查询到的表为空表则返回0 
	if(p==NULL){
		return 0;
	}

	//删除第i个结点 
	LNode *q=p->next;//定义一个新结点指向第i个结点 
	p->next=q->next; //删除第i个结点 
	e=q->data;       //把被删除的第i个结点数据域赋值给e 
	free(q);    //清空q结点的数据 
	return true;   //返回被删除的数据 
} 
//-----补充 操作------------- 
//1.判断单链表是否为空
int  EmptyList(LinkList L){
	if(L==NULL){
		return 1;
	}else{
		return 0;
	}	
} 
//2.销毁表L,销毁后不存在了 
bool DestoryList(LinkList &L){
	
	LNode *p;
	while(L){
		p=L;
		L=L->next;
		free(p); 
	}
	return true;
	}


 
int main(){
	
	LinkList L;        //定义一个表 
//	List_HeadInsert(L);  //头插法调用
    List_TailINsert(L) ;  //尾插法调用  
	int length=Length_List(L) ;//求表长 
	
    printf("插入前");
	LinkList_Printf(L);   //表的遍历 
	ListInsert_L(L,1,666) ; //将数据域为666的结点插入表L的第3个结点位置
	ListInsert_L(L,2,777) ;
	printf("插入后");
	LinkList_Printf(L);   //表的遍历
		
	ElemType e;
	int i=1; 				
	ListDelete_L(L,i,e);
	printf("删除后");
	LinkList_Printf(L);   //表的遍历
	printf("删除的元素为:%d\n",e);
	
//-------	获取表中每一个元素 
	for (int a=1;a<=length;a++){
	LNode *get_e=GetElem_1(L,a);
//	LNode *get_e=GetElem_2(L,a);
	printf("获取的第 %d 个元素为:%d\n",a,get_e->data);
	}

	DestoryList(L);
	LinkList_Printf(L);   //表的遍历
//	DestoryList(L);

	

}

你可能感兴趣的:(数据结构,链表)