单链表是方向单一的链表,即就是只能从前向后访问,不能从后向前访问。这篇文章,我
将整理出单链表的一些基本功能。
1.尾插 2.尾删 3.头插 4.头删5.打印 6.插入7.删除指定元素 8.删除指定元素的全部9.删除指
定位置的元素10.排序(此文先给出基本的冒泡排序,其他排序算法之后再给出)
下边,我就这些功能一个一个进行说明,尽量配图~~(这里的单链表不带头结点)
为了方便大家读以下的代码,我给出结构体的定义。
typedef struct LinkNode
{
DataType data;
struct LinkNode *next;
}LinkNode,*pLinkNode;
typedef struct LinkList
{
LinkNode *pHead;
}LinkList,*pLinkList;1.尾插:先要找到链表的尾部,然后进行插入。
具体实现代码如下:
void PushBackLinkList(pLinkList pList, DataType x)
{
assert(pList);
pLinkNode add = CreatNode(x);
pLinkNode tmp = pList->pHead;
if (NULL == pList->pHead)//linklist is empty
{
pList->pHead = add;
add->next = NULL;
return;
}
while (tmp->next)//linklist is not empty
{
tmp = tmp->next;
}
tmp->next = add;
add->next = NULL;
printf("successful push back\n");
}2.尾删:顾名思义,找到链表的结尾,将其删除。看图:
下边给出代码实现:
void PopBackLinkList(pLinkList pList)
{
assert(pList);
if (NULL == pList->pHead)
{
printf("linklist is empty.\n");
return;
}
pLinkNode cur = pList->pHead;
pLinkNode prev = pList->pHead;
if (NULL == cur->next->next)//linklist only has an element.
{
free(cur->next);
cur->next = NULL;
}
else
{
while (cur->next)
{
prev = cur;
cur = cur->next;
}
free(prev ->next);
prev->next = NULL;
}
printf("successful popback");
}3.头插:
如果链表是空链表,直接插入就可;有一个元素和有多个元素一样处理。下边图解:
下边给出代码实现:
void PushFrontLinkList(pLinkList pList, DataType x)
{
assert(pList);
pLinkNode add = CreatNode(x);
pLinkNode tmp = pList->pHead;
if (NULL == pList->pHead)//linklist is empty
{
pList->pHead = add;
add->next = NULL;
return;
}
add->next = tmp;
pList->pHead = add;
printf("successful pushfront.\n");
}4.头删:
如果链表是空,不删除;如果是一个结点,删除后将头指针置为NULL;如果是多个结
点,调整指针就好。图解:
下边给出代码实现:
void PopFrontLinkList(pLinkList pList)
{
assert(pList);
if (NULL == pList->pHead)
{
printf("linklist is empty.\n");
return;
}
pLinkNode tmp = pList->pHead;
pLinkNode del = pList->pHead;
if (NULL == tmp->next->next)
{
free(tmp->next);
pList->pHead = NULL;
}
else
{
del = tmp->next;
tmp = tmp->next->next;
free(del);
}
printf("successful popfront.\n");
}5.打印:这个比较简单。
6.指定位置之前插入指定元素:这个我们需要有个find函数来查找指定位置的指针
我们约定:如果是空链表,直接将元素插在链表中。
下边给出代码:
void InsertLinkList(pLinkList pList, DataType x, pLinkNode pos)//insert the front of pos
{
assert(pList);
pLinkNode p = CreatNode(x);
pLinkNode tmp = pList->pHead;
if (NULL == pList->pHead)//check:if linklist is empty,we insert the element in the linklist.
{
tmp->next = p;
p->next = NULL;
return;
}
if (pos == pList->pHead->next)
{
PushFrontLinkList(pList, x);
return;
}
while (tmp->next != pos)
{
tmp = tmp->next;
}
p->next = tmp->next;
tmp->next = p;
printf("successful insertion.\n");
}7.删除指定元素:
如果链表是空,直接返回;如果链表只有一个元素,如果第一个元素就是指定元素,删
除,然后返回;如果多个元素,找到元素直接删除。
代码:
void Remove(pLinkList pList, DataType x)
{
assert(pList);
pLinkNode cur = pList->pHead;
pLinkNode del = pList->pHead;
pLinkNode prev = pList->pHead;
if (NULL == pList->pHead)
{
printf("linklist is empty.\n");
return;
}
if (cur->next == NULL)//只有一个元素
{
if (cur->data == x)
{
free(cur->next);
pList->pHead = NULL;
return;
}
}
else
{
while (cur != NULL)
{
if (cur->data == x)
{
del = cur;
pList->pHead = cur->next;
free(del);
return;
}
cur = cur->next;
while (cur != NULL)
{
if (cur->data == x)
{
prev->next = cur->next;
free(cur);
return;
}
prev = cur;
cur = cur->next;
}
}
}
printf("successful remove.\n");
}8.删除指定元素的全部:
给定元素x,删除链表中所有data为x的元素。如果是空链表,直接返回。先判断链表的
第一个元素。
给出代码:
void RemoveAll(pLinkList pList, DataType x)
{
assert(pList);
if (NULL == pList->pHead)
{
printf("linklist is empty.\n");
return;
}
pLinkNode cur = pList->pHead;
pLinkNode prev = pList->pHead;
while (cur != NULL) //判断第一个结点
{
if (cur->next == NULL) //linklist has one element.
{
if (cur->data == x)
{
free(cur->next);
pList->pHead = NULL;
return;
}
}
else if (pList->pHead->data == x) //如果不是一个结点,且第一个结点的数据是x
{
pList->pHead = cur->next;
free(cur);
cur = pList->pHead;
}
else
break;
}
cur = cur->next;
prev = pList->pHead;
while (cur)
{
if (cur->data == x)
{
prev->next = cur->next;
free(cur);
cur = prev;
}
prev = cur;
cur = cur->next;
}
printf("successful removeall.\n");
}
9.删除指定位置的元素:
如果链表是空,直接返回;如果只有一个元素,如果这个元素就是pos位置,删除,返
回;如果多个元素,同样先判断第一个位置,如果是,直接删除,返回,如果不是,继
续向后找。
代码:
void Erase(pLinkList pList, pLinkNode pos)
{
assert(pList);
if (NULL == pList->pHead)
{
printf("linklist is empty.\n");
return;
}
pLinkNode cur = pList->pHead;
pLinkNode del = pList->pHead;
pLinkNode prev = pList->pHead;
if (cur->next == NULL)//如果只有一个元素
{
if (pos == cur)
{ //第一个结点就是pos位置
free(pList->pHead);
pList->pHead = NULL;
}
return;
}
if (pos == cur)
{ //第一个结点就是pos位置
del = cur;
pList->pHead = cur->next;
free(del);
return;
}
cur = cur->next;
while(cur)
{
if(cur == pos)
{
prev->next = cur->next;
free(cur);
return;
}
prev = cur;
cur = cur->next;
}
}10.冒泡排序:
给出代码:
void BottleSort(pLinkList pList)
{
assert(pList);
if (NULL == pList->pHead || NULL == pList -> pHead->next )
{
printf("linklist is empty or linklist has one element.\n");
return;
}
pLinkNode front = pList->pHead;
pLinkNode tail = NULL;
while (front != tail)
{
while (front->next != tail)
{
if (front->data > front->next->data)
{
DataType tmp = front->data;
front->data = front->next->data;
front->next->data = tmp;
}
front = front->next;
}
tail = front;
front = pList->pHead;
}
}为了方便读者理解,下边给出程序源码:
//LinkList.h
#ifndef __LINKLIST_H__
#define __LINKLIST_H__
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include <assert.h>
#include<stdlib.h>
typedef int DataType;
enum OP
{
EXIT,
PUSHBACK,
POPBACK,
PUSHFRONT,
POPFRONT,
PRINT,
INSERT,
REMOVE,
REMOVEALL,
ERASE,
SORT
};
typedef struct LinkNode
{
DataType data;
struct LinkNode *next;
}LinkNode,*pLinkNode;
typedef struct LinkList
{
LinkNode *pHead;
}LinkList,*pLinkList;
void InitLinkList(pLinkList pList);
void DestroyLinkList(pLinkList pList);
void PushBackLinkList(pLinkList pList,DataType x);
void PopBackLinkList(pLinkList pList);
void PushFrontLinkList(pLinkList pList, DataType x);
void PopFrontLinkList(pLinkList pList);
void PrintLinkList(pLinkList pList);
void InsertLinkList(pLinkList pList, DataType x, pLinkNode pos);
void Remove(pLinkList pList, DataType x);
void RemoveAll(pLinkList pList, DataType x);
void Erase(pLinkList pList, pLinkNode pos);
void BottleSort(pLinkList pList);
void menu();
#endif//__LINKLIST_H__
//LinkList.c
#include"LinkList.h"
pLinkNode CreatNode(DataType x)
{
pLinkNode p = (pLinkNode)malloc(sizeof(LinkNode));
if (NULL == p)
{
printf("out of memory.\n");
exit(EXIT_FAILURE);
}
p->data = x;
return p;
}
pLinkNode find(pLinkList pList,DataType x)
{
assert(pList);
pLinkNode tmp = pList->pHead;
if (pList->pHead == NULL)
{
printf("pList is empty.\n");
}
while (tmp->data != x)
{
tmp = tmp->next;
}
return tmp;
}
void InitLinkList(pLinkList pList)
{
assert(pList);
pList ->pHead = NULL;
}
void DestroyLinkList(pLinkList pList)
{
assert(pList);
pLinkNode p = pList->pHead;
pLinkNode del = NULL;
if (NULL == pList->pHead)
{
printf("linklist is empty.\n");
return;
}
while (p)
{
pList->pHead = p->next;
free(p);
p = pList->pHead;
}
pList->pHead = NULL;
}
void PushBackLinkList(pLinkList pList, DataType x)
{
assert(pList);
pLinkNode add = CreatNode(x);
pLinkNode tmp = pList->pHead;
if (NULL == pList->pHead)//linklist is empty
{
pList->pHead = add;
add->next = NULL;
return;
}
while (tmp->next)//linklist is not empty
{
tmp = tmp->next;
}
tmp->next = add;
add->next = NULL;
printf("successful push back\n");
}
void PopBackLinkList(pLinkList pList)
{
assert(pList);
if (NULL == pList->pHead)
{
printf("linklist is empty.\n");
return;
}
pLinkNode cur = pList->pHead;
pLinkNode prev = pList->pHead;
if (NULL == cur->next->next)//linklist only has an element.
{
free(cur->next);
cur->next = NULL;
}
else
{
while (cur->next)
{
prev = cur;
cur = cur->next;
}
free(prev ->next);
prev->next = NULL;
}
printf("successful popback");
}
void PushFrontLinkList(pLinkList pList, DataType x)
{
assert(pList);
pLinkNode add = CreatNode(x);
pLinkNode tmp = pList->pHead;
if (NULL == pList->pHead)//linklist is empty
{
pList->pHead = add;
add->next = NULL;
return;
}
add->next = tmp;
pList->pHead = add;
printf("successful pushfront.\n");
}
void PopFrontLinkList(pLinkList pList)
{
assert(pList);
if (NULL == pList->pHead)
{
printf("linklist is empty.\n");
return;
}
pLinkNode tmp = pList->pHead;
pLinkNode del = pList->pHead;
if (NULL == tmp->next->next)
{
free(tmp->next);
pList->pHead = NULL;
}
else
{
del = tmp->next;
tmp = tmp->next->next;
free(del);
}
printf("successful popfront.\n");
}
void PrintLinkList(pLinkList pList)
{
assert(pList);
if (NULL == pList->pHead)
{
printf("linklist is empty.\n");
return;
}
pLinkNode tmp = pList->pHead;
while (tmp)
{
printf("%d->",tmp->data);
tmp = tmp->next;
}
printf("over\n");
}
void InsertLinkList(pLinkList pList, DataType x, pLinkNode pos)//insert the front of pos
{
assert(pList);
pLinkNode p = CreatNode(x);
pLinkNode tmp = pList->pHead;
if (NULL == pList->pHead)//check:if linklist is empty,we insert the element in the linklist.
{
tmp->next = p;
p->next = NULL;
return;
}
if (pos == pList->pHead->next)
{
PushFrontLinkList(pList, x);
return;
}
while (tmp->next != pos)
{
tmp = tmp->next;
}
p->next = tmp->next;
tmp->next = p;
printf("successful insertion.\n");
}
void Remove(pLinkList pList, DataType x)
{
assert(pList);
pLinkNode cur = pList->pHead;
pLinkNode del = pList->pHead;
pLinkNode prev = pList->pHead;
if (NULL == pList->pHead)
{
printf("linklist is empty.\n");
return;
}
if (cur->next == NULL)//只有一个元素
{
if (cur->data == x)
{
free(cur->next);
pList->pHead = NULL;
return;
}
}
else
{
while (cur != NULL)
{
if (cur->data == x)
{
del = cur;
pList->pHead = cur->next;
free(del);
return;
}
cur = cur->next;
while (cur != NULL)
{
if (cur->data == x)
{
prev->next = cur->next;
free(cur);
return;
}
prev = cur;
cur = cur->next;
}
}
}
printf("successful remove.\n");
}
void RemoveAll(pLinkList pList, DataType x)
{
assert(pList);
if (NULL == pList->pHead)
{
printf("linklist is empty.\n");
return;
}
pLinkNode cur = pList->pHead;
pLinkNode prev = pList->pHead;
while (cur != NULL) //判断第一个结点
{
if (cur->next == NULL) //linklist has one element.
{
if (cur->data == x)
{
free(cur->next);
pList->pHead = NULL;
return;
}
}
else if (pList->pHead->data == x) //如果不是一个结点,且第一个结点的数据是x
{
pList->pHead = cur->next;
free(cur);
cur = pList->pHead;
}
else
break;
}
cur = cur->next;
prev = pList->pHead;
while (cur)
{
if (cur->data == x)
{
prev->next = cur->next;
free(cur);
cur = prev;
}
prev = cur;
cur = cur->next;
}
printf("successful removeall.\n");
}
void Erase(pLinkList pList, pLinkNode pos)
{
assert(pList);
if (NULL == pList->pHead)
{
printf("linklist is empty.\n");
return;
}
pLinkNode cur = pList->pHead;
pLinkNode del = pList->pHead;
pLinkNode prev = pList->pHead;
if (cur->next == NULL)//如果只有一个元素
{
if (pos == cur)
{ //第一个结点就是pos位置
free(pList->pHead);
pList->pHead = NULL;
}
return;
}
if (pos == cur)
{ //第一个结点就是pos位置
del = cur;
pList->pHead = cur->next;
free(del);
return;
}
cur = cur->next;
while(cur)
{
if(cur == pos)
{
prev->next = cur->next;
free(cur);
return;
}
prev = cur;
cur = cur->next;
}
}
void BottleSort(pLinkList pList)
{
assert(pList);
if (NULL == pList->pHead || NULL == pList -> pHead->next )
{
printf("linklist is empty or linklist has one element.\n");
return;
}
pLinkNode front = pList->pHead;
pLinkNode tail = NULL;
while (front != tail)
{
while (front->next != tail)
{
if (front->data > front->next->data)
{
DataType tmp = front->data;
front->data = front->next->data;
front->next->data = tmp;
}
front = front->next;
}
tail = front;
front = pList->pHead;
}
}
void menu()
{
printf("*********1.尾插***************\n");
printf("*********2.尾删***************\n");
printf("*********3.头插***************\n");
printf("*********4.头删***************\n");
printf("*********5.打印***************\n");
printf("*********6.插入***************\n");
printf("*********7.删除指定元素********\n");
printf("*********8.删除指定的全部*******\n");
printf("*********9.删除指定位置的元素***\n");
printf("*********10.排序****************\n");
printf("*********0.退出*******\n");
}
//test.c
#include"LinkList.h"
void test()
{
LinkList list;
pLinkNode pos = NULL;
InitLinkList(&list);
int input = 1;
DataType x = 0;
DataType y = 0;
while (input)
{
menu();
printf("please your choice:>");
scanf("%d",&input);
switch (input)
{
case EXIT:
DestroyLinkList(&list);
break;
case PUSHBACK:
printf("please input a number of insertion:>");
scanf("%d",&x);
PushBackLinkList(&list, x);
break;
case POPBACK:
PopBackLinkList(&list);
break;
case PUSHFRONT:
printf("please input a number of insertion:>");
scanf("%d", &x);
PushFrontLinkList(&list, x);
break;
case POPFRONT:
PopFrontLinkList(&list);
break;
case PRINT:
PrintLinkList(&list);
break;
case REMOVE:
printf("please input a number of delete:>");
scanf("%d", &x);
Remove(&list, x);
break;
case REMOVEALL:
printf("please input a number of delete:>");
scanf("%d", &x);
RemoveAll(&list, x);
break;
case ERASE:
printf("please input a number of delete:>");
scanf("%d", &x);
pos = find(&list,x);
Erase(&list, pos);
break;
case SORT:
BottleSort(&list);
break;
case INSERT:
printf("please input a number of insertion:>");
scanf("%d", &x);
printf("please input a number of the data of pos:>");
scanf("%d", &y);
pos = find(&list, y);
InsertLinkList(&list, x, pos);
break;
}
}
}
int main()
{
test();
system("pause");
return 0;
}就整理这么多,如果有问题,请指出~~
原文:http://blog.csdn.net/peiyao456/article/details/51626853