单链表的实现

一、Sysutil.h//系统头文件

#ifndef _SYSUTIL_H_
#define _SYSUTIL_H_

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<string.h>
#include<stdbool.h>
#include<windows.h>
#pragma warning (disable:4996)

#include<vld.h>  //内存泄漏工具的头文件

#endif

二、List.h//函数功能实现头文件

#include"Sysutil.h"

#define ElemType int
//无头单链表
typedef struct SListNode{
	ElemType data;//数据域
	struct SListNode *next;//指针域
}SListNode;

typedef struct SList{
	SListNode * head;
}SList;

void SListInit(SList *plist);
void SListInit(SList *plist);
void SListPushBack(SList *plist, ElemType x);
void SListPushFront(SList *plist, ElemType x);
void SListPopBack(SList *plist);
void SListPopFront(SList *plist);
void SListShow(SList *plist);

int SListLength(SList *plist);
SListNode *SeqListFind(SList *plist, ElemType x);
void SListClear(SList *plist);
void SListDestroy(SList *plist);

void SListDeleteByVal(SList *plist, ElemType x);
void SListInsertByVal(SList *plist, ElemType x);
void SListReverse(SList *plist);
void SListSort(SList *plist);
void SListRemoveAll(SList *plist,ElemType x);
SListNode* FindKthToTail(SList *plist, ElemType key);
SListNode* deleteDuplication(SList *plist);
SListNode* middleNode(SList *plist);

SListNode* _BuyNnode(){
	SListNode *s = malloc(sizeof(SListNode));
	assert(s != NULL);
	s->data = 0;
	s->next = NULL;
	return s;
}

void SListInit(SList *plist)
{
	plist->head = NULL;
}
void SListPushBack(SList *plist, ElemType x){
	assert(plist);
	SListNode* s = _BuyNnode();
	s->data = x;

	SListNode *p = plist->head;//查找到链表的尾部;

	if (p ==NULL){
		plist->head = s;
	}
	else{
		while (p ->next!= NULL){
			p = p->next;
		}
		p->next = s;
	}
}
void SListPushFront(SList *plist, ElemType x){
	assert(plist);

	SListNode *s = _BuyNnode();
	s->data = x;
	s->next = plist->head;

	plist->head = s;
}
void SListPopBack(SList *plist){
	assert(plist);

	SListNode *p = plist->head;
	

	if (p != NULL){
		if (p->next == NULL){
			plist->head= NULL;
		}
		else{
			SListNode *pre = NULL;
			while (p ->next!= NULL){
				pre = p;
				p = p->next;
			}
			pre->next = NULL;
		}
		free(p);
	}
}
void SListPopFront(SList *plist){
	assert(plist);
	SListNode *p = plist->head;
	if (p != NULL){
		plist->head = p->next;
		free(p);
	}
}
void SListShow(SList *plist){
	assert(plist);
	SListNode * p = plist->head;
	while (p != NULL){
		printf("%d->", p->data);
		p = p->next;
	}
	printf("Over.\n");
}
int SListLength(SList *plist){
	assert(plist);
	SListNode *p = plist->head;
	int Len=0;

	while (p != NULL){
		Len++;
		p = p->next;
	}
	return Len;
}
SListNode *SeqListFind(SList *plist, ElemType x){
	assert(plist);
	SListNode * p = plist->head;

	//找到返回节点地址,找不到返回NULL

	while (p != NULL&&p->data != x){
		p = p->next;
	}
	return p;
}
void SListClear(SList *plist){
	assert(plist);
	SListNode * p = plist->head;

	while (p != NULL){
		plist->head = p->next;
		free(p);
		p = plist->head;
	}
}
void SListDestroy(SList *plist)
{
	SListClear(plist);
}
void SListDeleteByVal(SList *plist, ElemType x){
	assert(plist);
	SListNode *p = plist->head;
	SListNode *pre = NULL;

	while (p != NULL&&p->data != x){
		pre = p;
		p = p->next;
	}

	if (p != NULL){
		if (pre == NULL){
			plist->head = p->next;//如果删除的是头节点的值的话,pre就是NULL
		}
		else{
			pre->next = p->next;
		}
		free(p);
	}
}
void SListInsertByVal(SList *plist, ElemType x){
	assert(plist);
	SListNode *s =_BuyNnode();
	s->data = x;

	if (plist->head == NULL){
		plist->head = s;
	}
	else{
		SListNode *p = plist->head;
		SListNode *pre = NULL;

		while (p!=NULL&&x > p->data){
			pre = p;
			p = p->next;
		}
		
		if (pre == NULL)//在链表的头部插入
		{
			s->next = p;
			plist->head = s;
		}
		else{
			s->next = pre->next;
			pre->next = s;
		}
	}
}
void SListReverse(SList *plist){
	assert(plist);
	SListNode *p, *q;

	if (plist->head == NULL)//没有节点,不需要转置
	{
		return;
	}
	else if (plist->head->next == NULL)//只有一个节点,不需要转置
	{
		return;
	}

	//1.切割链表
	p = plist->head->next;
	plist->head->next = NULL;

	//2.将剩余链表的节点进行一一头插
	q = p;
	while (q != NULL){
		q = q->next;
		p->next = plist->head;
		plist->head = p;
		p = q;
	}

}
void SListSort(SList *plist){
	assert(plist);

	SListNode *p, *q;
	if (plist->head == NULL || plist->head->next == NULL)//一个节点都没有或者只有一个节点,不需要排序
		return;

	//断开链表
	p = plist->head->next;
	plist->head->next = NULL;
	
	//循环按值插入
	q = p;
	while (q != NULL){
		q = q->next;
		SListNode *t = plist->head;
		SListNode *pre = NULL;

		while (t != NULL&&p->data > t->data)//寻找插入位置
		{
			pre = t;
			t = t->next;
		}
		if (pre == NULL) //在头部插入
		{
			p->next = plist->head;
			plist->head = p;
		}
		else//这里是找到了插入位置,进行插入
		{
			p->next = pre->next;//让p的next指向空
			pre->next = p;//让pre指向p
		}
		p = q;//再开始寻找
	}
	
}
void SListRemoveAll(SList *plist, ElemType key){
	assert(plist);

	SListNode *p, *pre = NULL;

	if (plist->head == NULL)
		return;

	p = plist->head;

	while (p != NULL)
	{
		if (p->data == key)
		{
			if (pre == NULL)
				plist->head = p->next;
			else
				pre->next = p->next;

			free(p);
		}
		else
			pre = p;

		if (pre == NULL)
			p = plist->head;
		else
			p = pre->next;
	}
}
SListNode* FindKthToTail(SList *plist, ElemType key)
{
	if (plist == NULL)
		return NULL;
	SListNode *fast, *slow;
	fast = slow = plist->head;
	while (key-- > 0)
	{
		if (fast == NULL)//用于判断是否超出节点的个数
			return NULL;
		fast = fast->next;
	}

	while (fast != NULL)
	{
		fast = fast->next;
		slow = slow->next;
	}
	return slow;
}
SListNode* deleteDuplication(SList *plist)
{
	if (plist ->head->next== NULL || plist->head == NULL)
		return plist->head;
	SListNode *pre = NULL;
	SListNode *cur = plist->head;
	SListNode *next_node = plist->head->next;

	while (next_node != NULL)
	{
		if (cur->data != next_node->data) // 重复值出现
		{
			pre = cur;
			cur = next_node;
			next_node = next_node->next;
		}
		else
		{
			while (next_node && next_node->data == cur->data)
				next_node = next_node->next;

			if (pre == NULL)
				plist->head = next_node;
			else
				pre->next = next_node;

			//删除重复节点
			while (cur != next_node)
			{
				SListNode *p = cur;
				cur = cur->next;
				free(p);
			}
			if (next_node != NULL)
				next_node = next_node->next;
		}
	}
	return plist->head;
}
SListNode* middleNode(SList *plist)
{
	SListNode *fast, *slow;
	fast = slow = plist->head;
	while (fast && fast->next != NULL)
	{
		fast = fast->next->next;
		slow = slow->next;
	}
	return slow;
}

三、TestMain.c源文件

#include"List.h"


int main(){
	SList mylist;
	SListInit(&mylist);

	ElemType item, key;
	int pos;

	SListNode *p;

	int select = 1;
	while (select)
	{
		printf("********************************************\n");
		printf("* [1] push_back        [2] push_front      *\n");
		printf("* [3] show_list        [0] quit_system     *\n");
		printf("* [4] pop_back         [5] pop_front       *\n");
		printf("* [6] length           [7] middleNode      *\n");
		printf("* [8] insert_val       [*9] insert_pos     *\n");
		printf("* [10] delete_val      [11] deleteDuplicat *\n");
		printf("* [12] find            [13] sort           *\n");
		printf("* [14] reverse         [15] remove_all     *\n");
		printf("* [16] clear           [*17] destroy       *\n");
		printf("* [18] FindKthTo_Tail                         *\n");
		printf("********************************************\n");
		printf("请选择:>");
		scanf("%d", &select);
		switch (select)
		{
		case 1:
			printf("请输入要插入的数据(以-1结束):>");
			while (scanf("%d", &item), item != -1)  //逗号表达式
				SListPushBack(&mylist, item);
			break;
		case 2:
			printf("请输入要插入的数据(以-1结束):>");
			while (scanf("%d", &item), item != -1)  //逗号表达式
				SListPushFront(&mylist, item);
			break;
		case 3:
			SListShow(&mylist);
			break;
		case 4:
			SListPopBack(&mylist);
			break;
		case 5:
			SListPopFront(&mylist);
			break;
		case 6:
			printf("表长为:>%d\n", SListLength(&mylist));
			break;
		case 7:
			p = middleNode(&mylist);
			printf("中间节点是%d\n", p->data);
			break;
		case 8:
			printf("请输入要插入的值:>");
			scanf("%d", &item);
			SListInsertByVal(&mylist, item);
			break;
		case 9:
			printf("请输入要插入的位置:>");
			scanf("%d", &pos);
			printf("请输入要插入的值:>");
			scanf("%d", &item);
			//SeqListInsertByPos(&mylist, pos, item);
			break;
		case 10:
			printf("请输入要删除的值:>");
			scanf("%d", &key);
			SListDeleteByVal(&mylist, key);
			break;
		case 11:
			deleteDuplication(&mylist);
			break;
		case 12:
			printf("请输入要查找的值:>");
			scanf("%d", &key);
			p = SeqListFind(&mylist, key);
			if (p == NULL)
				printf("要查找的值%d不存在.\n", key);
			else
				printf("要查找的值%d存在.\n", key);
			break;
		case 13:
			SListSort(&mylist);
			break;
		case 14:
			SListReverse(&mylist);
			break;
		case 15:
			printf("请输入要删除的值:>");
			scanf("%d", &key);
			SListRemoveAll(&mylist, key);
			break;
		case 16:
			SListClear(&mylist);
			break;
		case 18:
			printf("请输入要查找的值:>");
			scanf("%d", &key);
			p=FindKthToTail(&mylist, key);
			if (p == NULL)
				printf("%d不存在.\n", key);
			else
				printf("倒数第%d值%d存在.\n", key,p->data);
			break;
		}
		system("pause");
		system("cls");
	}

	SListDestroy(&mylist);

	system("pause");
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值