一、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;
}