链表的基本操作

实现链表的增删,翻转
LinkList.h

#pragma once
   
typedef int DataType;
//链表节点信息
typedef struct LinkList {
	DataType Pdata;
	struct LinkList* next;       
}LinkList,*PNode;
  
//链表的结构信息,给一个头指针保存链表第一个节点的地址
typedef struct PLink {
	PNode PHead;          //指针类型
}PLink;

// 链表的初始化 
void LinkListInit(PLink* ps);

//创建一个新的节点
PNode CreateNewNode(DataType data);

// 在链表的尾部插入值为data的元素 
void LinkListPushBack(PLink* ps, DataType data);

// 删除链表最后一个元素 
void LinkListPopBack(PLink* ps);

// 在链表的头部插入值为data的元素 
void LinkListPushFront(PLink* ps, DataType data);

// 删除链表头部的元素 
void LinkListPopFront(PLink* ps);

// 在链表pos位置插入值为data的元素 
void LinkListInsert( PNode pos, DataType data);

// 删除链表中pos位置上的元素 
void LinkListErase(PLink* ps,PNode pos);

// 在链表中查找值为data的元素,找到返回该元素在链表中的地址,否则返回NULL,返回的地址00000000
PNode LinkListFind(PLink* ps, DataType data);

// 检测链表是否为空,如果为空返回非0值,非空返回0 
int LinkListEmpty(PLink* ps);

// 返回链表中节点的的个数 
int LinkListSize(PLink* ps);

//链表翻转
PNode LinkListReturn(PLink* ps);

// 删除链表中第一个值为data的元素 
void LinkListRemove(PLink* ps, DataType data);

// 销毁链表 
void LinkListDestroy(PLink* ps);

//打印
void LinkListPrint(PLink* ps);

LinkList.c

// 链表的初始化 
void LinkListInit(PLink* ps) {
	assert(ps);
	ps->PHead = NULL;
}

//创建一个新的节点
PNode CreateNewNode(DataType data) {
	PNode PnewNode = (PNode)malloc(sizeof(LinkList));
	if (PnewNode == NULL) {
		return NULL;
	}
	PnewNode->Pdata = data;
	PnewNode->next = NULL;
	return PnewNode;
}

// 在链表的尾部插入值为data的元素 
void LinkListPushBack(PLink* ps, DataType data) {
	assert(ps);
	PNode PnewNode = CreateNewNode(data);
	//链表为空
	if (ps->PHead == NULL) {  
        ps->PHead = PnewNode;  
	}
	//链表不为空
	else {
	    PNode Ptmp = ps->PHead;
		while(Ptmp->next != NULL) {
			Ptmp = Ptmp->next;
		}
		Ptmp->next= PnewNode;	
    }
}

 //删除链表最后一个元素 
void LinkListPopBack(PLink* ps) {
	assert(ps);
	//ps中没节点
	if (ps->PHead == NULL) {
        return;
	}
	//ps只有一个节点
	if (ps->PHead->next == NULL) {
		free(ps->PHead);
		ps->PHead = NULL;
	}
	//ps有多个节点
	PNode Pptr = NULL;
	PNode Ptmp = ps->PHead;
	while (Ptmp->next != NULL) {
		Pptr = Ptmp;
		Ptmp = Ptmp->next;
	}
	free(Ptmp);
	Pptr->next = NULL;
}	

// 在链表的头部插入值为data的元素 
void LinkListPushFront(PLink* ps, DataType data) {
	assert(ps);
	PNode PnewNode = CreateNewNode(data);
	PnewNode->next = ps->PHead;
	ps->PHead = PnewNode;
}

// 删除链表头部的元素 
void LinkListPopFront(PLink* ps) {
	assert(ps);
	if (ps->PHead == NULL) {
		return;
	}
	PNode Ptmp = ps->PHead;
	ps->PHead = ps->PHead->next;
	free(Ptmp);
}

// 在链表pos位置插入值为data的元素 (在pos的后面)
void LinkListInsert( PNode pos, DataType data) {
	if (pos == NULL) {
		return;
	}
	PNode PNewNode = CreateNewNode(data);
	PNewNode->next = pos->next;
	pos->next = PNewNode;
}

// 删除链表中pos位置上的元素 
void LinkListErase(PLink* ps, PNode pos) {
	assert(ps);
	if (pos == NULL || ps->PHead == NULL) {
		return;
	}
	if (pos == ps->PHead) {
		ps->PHead = pos->next;
	}
	else {
		PNode Ppos = ps->PHead;
		while (Ppos != NULL && Ppos->next != pos) {
			Ppos = Ppos->next;
		}
		if(Ppos!=NULL){
			Ppos->next = pos->next;
		}
	}
    free(pos);
}

// 在链表中查找值为data的元素,找到返回该元素在链表中的地址,否则返回NULL,返回的地址00000000
PNode LinkListFind(PLink* ps, DataType data) {
	assert(ps);
	PNode Ptmp = ps->PHead;
	while (Ptmp!=NULL) {
		if (Ptmp->Pdata == data) {
			return Ptmp;
		}
		Ptmp = Ptmp->next;
	}
	return NULL;
}

// 返回链表中节点的的个数 
int LinkListSize(PLink* ps) {
	assert(ps);
	size_t count = 0;
	PNode Ptmp = ps->PHead;
	while (Ptmp != NULL) {
		count++;
		Ptmp = Ptmp->next;
	}
	return count;
}

//检测链表是否为空,如果为空返回非0值,非空返回0
int LinkListEmpty(PLink* ps) {
	assert(ps);
	if (ps->PHead == NULL)
		return 1;
	return 0;
}

// 删除链表中第一个值为data的元素 
void LinkListRemove(PLink* ps, DataType data) {
	PNode Pptr = NULL;
	PNode Ptmp = ps->PHead;
	while (Ptmp) {
		if (Ptmp->Pdata == data) {
			if (Ptmp == ps->PHead) {
				ps->PHead = Ptmp->next;
			}
			else {
				Pptr->next = Ptmp->next;
			}
			free(Ptmp);
			return;
		}
		Pptr = Ptmp;
		Ptmp = Ptmp->next;
	}
}

//链表反转
PNode LinkListReturn(PLink* ps) {
	assert(ps);
	PNode Pptr = NULL;   //
	PNode Ptmp =ps->PHead;
	while (Ptmp != NULL) {
		PNode next = Ptmp->next;
		//头插,形成反转
		Ptmp->next =Pptr ;
		Pptr = Ptmp;
		Ptmp = next;
	}
	return Pptr;
}

// 销毁链表    
void LinkListDestroy(PLink* ps) {
	assert(ps); 
	PNode Pptr = ps->PHead->next;
	PNode Ptmp = ps->PHead;
	while (Pptr != NULL) {
		free(Ptmp);
		Ptmp = Pptr;
        Pptr = Pptr->next;		
	}
	free(Ptmp);
}

//打印
void LinkListPrint(PLink* ps) {
	assert(ps);
	PNode Ptmp = ps->PHead;
	while (Ptmp!=NULL) {
		printf("%d->", Ptmp->Pdata);
		Ptmp = Ptmp->next;
	}
	printf("NULL\n");
}

void main() {
	PLink ps;
	// 链表的初始化 
	LinkListInit(&ps);

	// 在链表的尾部插入值为data的元素 
	LinkListPushBack(&ps, 1);
	LinkListPushBack(&ps, 2);
	LinkListPushBack(&ps, 3);
	LinkListPushBack(&ps, 4);
	LinkListPushBack(&ps, 5);
	LinkListPrint(&ps);        //打印,查看结果

	// 删除链表最后一个元素 
	LinkListPopBack(&ps); 
	LinkListPrint(&ps);       //打印,查看结果

	// 在链表的头部插入值为data的元素 
	LinkListPushFront(&ps,0);
	LinkListPrint(&ps);        //打印,查看结果
 
	// 删除链表头部的元素 
	LinkListPopFront(&ps);
	LinkListPrint(&ps);         //打印,查看结果

	// 在链表pos位置插入值为data的元素 
	LinkListInsert(LinkListFind(&ps, 1) ,1);
	LinkListPrint(&ps);          //打印,查看结果

	// 删除链表中pos位置上值为data的元素 
	LinkListErase(&ps, LinkListFind(&ps, 1));
	LinkListPrint(&ps);           //打印,查看结果
 
	// 在链表中查找值为data的元素,找到返回该元素在链表中的位置,否则返回NULL,返回的地址00000000
	//此处结果, 返回结果为函数 LinkListInsert(); 的第一个参数
	//此处结果, 返回结果为函数 LinkListErase(); 的第二个参数
	printf("%p\n", LinkListFind(&ps, 5));       //打印地址


	// 返回链表中节点的的个数
	int ret=LinkListSize(&ps);
	printf("节点有%d个\n",ret);      
	
	// 检测链表是否为空,如果为空返回1,非空返回0
	int rte=LinkListEmpty(&ps);
	printf("rte=%d\n", rte);
	
	//链表反转
	printf("反转前的链表:");
	LinkListPrint(&ps); 
	PNode result= LinkListReturn(&ps);
	printf("反转后的链表:");
	while (result != NULL) {
		printf("%d->", result->Pdata);
		result = result->next;
	}
	printf("NULL\n");
    
    //删除链表中第一个值为data的元素 
	LinkListRemove(&ps, 2);
	LinkListPrint(&ps);
	
	// 销毁链表 
    LinkListDestroy(&ps);
    
	system("pause");
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值