SeqList.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>
typedef int DataType;
typedef struct Node
{
struct Node* next;
DataType Data;
}Node;
void PushBack(Node**pphead,DataType x);//尾插
Node *BuyNode(DataType x);//创建结点
void Init(Node**pphead);//初始化链表
void PrintSeqlist(Node*phead);//打印链表
void*Find(Node*phead, DataType x);//在链表中查找某一结点
void PrintTailToHeadR(Node * phead);//从尾到头打印单链表递归
void PrintTailToHead(Node * phead);//非递归
void EraseNotTail(Node *pos);//删除无头单链表非尾结点
void InsertFront1(Node*pos, DataType x);//在一个无头单链表某个结点前插入一个结点 方法1
void InsertFront2(Node*pos, DataType x);//方法2
void Revese(Node**pphead);//逆置/反转单链表
Node * Josephus1(Node * hus, int k);//实现约瑟夫环问题 方法1
Node * Josephus2(Node * hus, int k);//方法2
Node * FindMidNodeF1(Node*phead);//方法1:如果结点个数是偶数,返回中间两个结点中的前一个结点
Node * FindMidNodeF2(Node*phead);//方法2:如果结点个数是偶数,返回中间两个结点中的前一个结点
Node * FindMidNodeL(Node*phead);//如果结点个数是偶数,返回中间两个结点中的后一个结点
Node * FindLastk(Node *phead,int k);//查找单链表的倒数第k个结点
Node * MergeList(Node*list1, Node*list2);//合并两个有序链表
void Sortlist(Node*phead);//单链表排序
SeqList.c
#include"Seqlist.h"
void PushBack(Node**pphead,DataType x)
{
assert(pphead);
Node *tmp=*pphead;
if (*pphead == NULL)
{
*pphead = BuyNode(x);
}
else
{
while (tmp->next)
{
tmp = tmp->next;
}
tmp->next = BuyNode(x);
}
}
Node *BuyNode(DataType x)
{
Node*tmp = (Node*)malloc(sizeof(Node));
tmp->next = NULL;
tmp->Data = x;
return tmp;
}
void Init(Node**pphead)
{
assert(pphead);//判断参数
*pphead =NULL;
}
void PrintSeqlist(Node*phead)
{
Node *tmp = phead;
if (phead == NULL)
{
printf("NULL");
}
while (tmp)
{
printf("%d->", tmp->Data);
tmp = tmp->next;
}
printf("NULL\n");
}
void*Find(Node*phead, DataType x)
{
assert(phead);
Node *cur = phead;
while (cur)
{
if (cur->Data == x)
{
return cur;
}
cur = cur->next;
}
return NULL;
}
/
///链表面试题
/
//1.从尾到头打印单链表
void PrintTailToHeadR(Node * phead)//递归的思想从尾到头打印单链表
{
if (phead == NULL)//如果为空直接返回
{
return ;
}
if (phead->next == NULL)//有一个结点直接打印
{
printf("%d ", phead->Data);
}
else//多个结点递归打印
{
PrintTailToHeadR(phead->next);
printf("%d ", phead->Data);
}
}
void PrintTailToHead(Node * phead)
{
Node *tail = NULL;
if (tail == phead)//如果为空不打印
{
return;
}
while (tail != phead)
{
Node *cur = phead;//弄两个指针,一个cur每次从头遍历,一个tail记录所要打印结点的next(最开始置为空,打印一个更新一次,直到tail与phead相等结束)
while (cur->next != tail)
{
cur = cur->next;
}
printf("%d ", cur->Data);
tail = cur;
}
printf("\n");
}
//2.删除无头单链表非尾结点
void EraseNotTail(Node *pos)
{
assert(pos &&(pos->next) );//1检查参数
Node*Next = pos->next;
pos->next = Next->next;
pos->Data = Next->Data;
free(Next);
Next = NULL;
}
//3.在一个无头单链表某个结点前插入一个结点
void InsertFront1(Node*pos, DataType x)
{
Node *cur= BuyNode(x);//1.创建要插入的结点
Node *Next = pos->next;//2.保存指定插入位置的下一个结点
pos->next = cur;//3.在指定位置后面插入,把结点连接起来
cur->next = Next;
int tmp= pos->Data;//4.交换指定位置和插入位置元素的值
pos->Data = cur->Data;
cur->Data = tmp;
}
void InsertFront2(Node*pos, DataType x)
{
Node *cur = BuyNode(x);//1.创建要插入的结点
Node *Next = pos->next;//2.保存指定插入位置的下一个结点
pos->next = cur;//3.在指定位置后面插入,把结点连接起来
cur->next = Next;
cur->Data = pos->Data;//4.为结点赋值
pos->Data = x;
}
//4.逆置/反转单链表
void Revese(Node**pphead)
{
assert(pphead);
Node *prev = NULL;//逆置后新链表的头
Node*cur = *pphead;//用来遍历链表,往prev上插
Node*Next = (*pphead)->next;//记录下一个结点位置
while (cur)
{
cur->next = prev;//1.逆置
//2.后移动
prev = cur;
cur = Next;
if (Next != NULL)
{
Next = Next->next;
}
}
*pphead = prev;//3.传逆置后链表的头
}
//5.单链表实现约瑟夫环
Node * Josephus1(Node * hus, int k)//传统删除方法
{
assert(hus&&k > 0);
Node* man = hus;//找要删除的结点的前一个结点
Node* del = hus;//要删除的结点
while (man->next !=man)
{
int count = k-1;
while (--count)
{
man = man->next;
del = man;
}
del = del->next;
Node*Next = del->next;//要删除结点下一个结点
man->next = Next;//删除结点del
free(del);
}
return man;
}
Node * Josephus2(Node * hus, int k)//替换删除法
{
assert(hus&&k > 0);
Node* man = hus;//找要删除的结点的前一个结点
while (man->next != man)
{
int count = k;
while (--count)
{
man = man->next;
}
Node *Next = man->next;//2.替换法删除
man->Data = Next->Data;
man->next = Next->next;
free(Next);
Next = NULL;
}
return man;
}
//6.查找单链表的中间结点
Node * FindMidNodeF1(Node*phead)// 方法1:如果结点个数是偶数,返回中间两个结点中的前一个结点
{
assert(phead);
Node *fast = phead;
Node *slow = phead;
while (fast&&fast->next )
{
fast = fast->next->next ;
if (fast)
{
slow = slow->next;
}
}
return slow;
}
Node * FindMidNodeF2(Node*phead)// 方法2:如果结点个数是偶数,返回中间两个结点中的前一个结点
{
assert(phead);
Node *fast = phead;
Node *slow = phead;
while (fast&&fast->next&&(fast->next ->next) )
{
fast = fast->next->next;
slow = slow->next;
}
return slow;
}
Node * FindMidNodeL(Node*phead)//如果结点个数是偶数,返回中间两个结点中的后一个结点
{
assert(phead);
Node *fast = phead;
Node *slow = phead;
while (fast&&fast->next)
{
fast = fast->next->next;
slow = slow->next;
}
return slow;
}
//7.查找单链表的倒数第k个结点
Node * FindLastk(Node *phead, int k)
{
assert(phead);
Node* fast = phead;
Node*slow = phead;
while (--k)
{
fast = fast->next;
}
while (fast->next !=NULL)
{
fast = fast->next;
slow = slow->next;
}
return slow;
}
//8.合并两个有序链表
Node *MergeList(Node*list1, Node*list2)
{
Node*list,*tail;
if (list1 == NULL)
{
return list2;
}
else if (list2 == NULL)
{
return list1;
}
if ((list1->Data) < (list2->Data))
{
list = list1;
list1 = list1->next;
}
else
{
list = list2;
list2 = list2->next;
}
tail = list;
while (list1&&list2)
{
if ((list1->Data) < (list2->Data))
{
tail->next = list1;
list1 = list1->next;
}
else
{
tail->next = list2;
list2 = list2->next;
}
tail = tail->next;
}
if (list1)
{
tail->next =list1;
}
if (list2)
{
tail->next =list2;
}
return list;
}
//9.单链表排序
void Sortlist(Node*phead)
{
if (phead == NULL)//不能用断言 空链表也是有序的
{
return;
}
Node *tail = NULL;
int tmp;
while (tail != phead)//排几趟
{
Node* Next = phead->next;
Node* cur = phead;
while (Next != tail)//每趟排序
{
if ((cur->Data )> (Next->Data))
{
tmp = cur->Data;
cur->Data = Next->Data;
Next->Data = tmp;
}
cur = cur->next;
Next = Next->next;
}
tail = cur;
}
}
test.c
#include"Seqlist.h"
void fun1()//测试PrintTailToHeadR PrintTailToHead
{
Node *list;
Init(&list);
PushBack(&list, 1);
PushBack(&list, 2);
PushBack(&list, 3);
PushBack(&list, 4);
PushBack(&list, 5);
PrintSeqlist(list);
PrintTailToHeadR(list);
PrintTailToHead(list);
}
void fun2()//测试EraseNotTail InsertFront2 InsertFront1 Reverse
{
Node *list;
Init(&list);
PushBack(&list, 1);
PushBack(&list, 2);
PushBack(&list, 3);
PushBack(&list, 4);
PushBack(&list, 5);
PrintSeqlist(list);
EraseNotTail(list->next );
PrintSeqlist(list);
InsertFront2(list->next, 2);
PrintSeqlist(list);
InsertFront1(list->next, 2);
PrintSeqlist(list);
Revese(&list);
PrintSeqlist(list);
}
void fun3()//测试Josephus
{
Node *list;
Init(&list);
PushBack(&list, 1);
PushBack(&list, 2);
PushBack(&list, 3);
PushBack(&list, 4);
PushBack(&list, 5);
Node * tmp = Find(list, 5);
tmp->next = list;
Node * man=Josephus2(list, 3);
printf("%d", man->Data);
}
void fun4()//FindMidNode系列 FindLastk
{
Node *list;
Init(&list);
PushBack(&list, 1);
PushBack(&list, 2);
PushBack(&list, 3);
PushBack(&list, 4);
PushBack(&list, 5);
PushBack(&list, 6);
Node* cur = FindMidNodeL(list);
printf("%d\n", cur->Data);
Node *tmp = FindLastk(list, 3);
printf("%d\n", tmp->Data);
}
void fun5()//测试MergeList
{
Node*list1;
Node*list2;
Init(&list1);
PushBack(&list1, 3);
PushBack(&list1, 5);
PushBack(&list1, 9);
Init(&list2);
PushBack(&list2, 3);
PushBack(&list2, 4);
PushBack(&list2, 7);
Node *list=MergeList(list1, list2);
PrintSeqlist(list);
}
void fun6()//测试Sortlist
{
Node *list;
Init(&list);
PushBack(&list, 1);
PushBack(&list, 4);
PushBack(&list, 3);
PushBack(&list, 2);
PushBack(&list, 9);
PushBack(&list, 6);
Sortlist(list);
PrintSeqlist(list);
}
int main()
{
//fun1();
//fun2();
//fun3();
//fun4();
//fun5();
fun6();
system("pause");
return 0;
}