封装链表库实现单链表:增加,删除,查询,修改,排序,逆转

来源:互联网 发布:win7 nginx 域名绑定 编辑:程序博客网 时间:2024/04/30 04:53
/****************************************************************
*文件名:linknode.h
*创建者:ycj
*创建时间:2015-3-12
*文件说明:声明单链表:增加,删除,查询,修改,排序,逆转

*****************************************************************/

#include <stdio.h>
#include <stdlib.h>


#define datatype int
struct node
{
int num;//编号
datatype data;//存储的数据
struct node *pNext;
};
typedef struct node Node;//简写
/*函数设计的思想:
改变一个变量需要变量的地址
改变一个指针需要指针的地址(不用二级指针,必须要用返回值赋值)
*/


void backaddnode(Node **ppnode, int num, datatype data);//增加结点
Node * backaddnodeA(Node *pnode, int num, datatype data);//增加结点


void showallnode(Node *pnode);//显示所有的结点


Node * searchfirst(Node *pnode, int num);//查询


int change(Node *pnode, int oldnum, int newnum);//修改失败返回0,成功返回1


Node * rev(Node *pnode);//链表的逆转


Node * deletenode(Node *pnode, int num);//删除


Node * insert(Node *pnode, int findnum, int newnum, datatype data);//前面插入数据


void sort(Node *pnode, char ch);//ch == > 从大到小 ch == < 从小到大





/****************************************************************
*文件名:linknode.c
*创建者:ycj
*创建时间:2015-3-12
*文件说明:实现单链表:增加,删除,查询,修改,排序,逆转

*****************************************************************/

#include "linknode.h"


//法1:增加结点(二级指针)
void backaddnode(Node **ppnode, int num, datatype data)
{
Node *pnewnode =(Node *)malloc(sizeof(Node));
pnewnode->num = num;//赋值
pnewnode->data = data;//赋值
if (*ppnode == NULL)
{
*ppnode = pnewnode;//存储新建结点的地址(不能直接使用头指针因为函数有副本机制)
}
else
{
Node *p = *ppnode;//等于头结点
while (p->pNext != NULL)
{
p = p->pNext;//一直循环到最后一个结点的地址
}
p->pNext = pnewnode;//尾部插入
}
pnewnode->pNext = NULL;
}
//法2:增加结点
Node * backaddnodeA(Node *pnode, int num, datatype data)
{
Node *pnewnode = (Node *)malloc(sizeof(Node));
pnewnode->num = num;//赋值
pnewnode->data = data;//赋值
if (pnode == NULL)
{
pnode = pnewnode;//存储新建结点的地址
}
else
{
Node *p = pnode;//等于头结点
while (p->pNext != NULL)
{
p = p->pNext;//一直循环到最后一个结点的地址
}
p->pNext = pnewnode;//尾部插入
}
pnewnode->pNext = NULL;


return pnode;
}


//显示所有的结点
void showallnode(Node *pnode)
{
printf("打印链表:\n");
while (pnode != NULL)
{
printf("%p,%p ", pnode, pnode->pNext);
printf("%d,%d\n", pnode->num, pnode->data);
pnode = pnode->pNext;
}
}


//查询
Node * searchfirst(Node *pnode, int num)
{
for (Node *p = pnode; p != NULL; p = p->pNext)
{
if (p->num == num)
{
return p;//返回找到的地址
}
}


return NULL;
}


//修改失败返回0,成功返回1
int change(Node *pnode, int oldnum, int newnum)
{
while (pnode != NULL)
{
if (oldnum == pnode->num)//判断
{
pnode->data = newnum;//修改
return 1;
}
pnode = pnode->pNext;//循环趋于终止
}


return 0;
}


Node * rev(Node *pnode)//链表的逆转
{
Node *p1, *p2, *p3;
p1 = p2 = p3 = NULL;//避免野指针
if (pnode == NULL || pnode->pNext == NULL)
{
return pnode;//返回头结点
}
else
{
p1 = pnode;
p2 = pnode->pNext;
while (p2 != NULL)
{
p3 = p2->pNext;//布局第三个结点(保留)
p2->pNext = p1;//地址转向
p1 = p2;//循环前移
p2 = p3;
}
pnode->pNext = NULL;//原来首结点的下一个为NULL
pnode = p1;//存储头结点地址
}


return pnode;
}


Node * deletenode(Node *pnode, int num)//删除
{
Node *p1 = NULL, *p2 = NULL;
p1 = pnode;


while (p1 != NULL)//查找结点位置
{
if (p1->num == num)
{
//p1保存了要删除结点的地址
break;
}
else
{
p2 = p1;//p2保存找到结点的上一个结点
p1 = p1->pNext;//循环前移
}
}


if (p1 == pnode)//删除第一个结点
{
pnode = p1->pNext;//跳过这个结点(函数有副本机制,头结点有改变,需要返回头结点)
free(p1);
}
else//删除其余结点
{
p2->pNext = p1->pNext;
free(p1);
}

return pnode;
}




Node * insert(Node *pnode, int findnum, int newnum, datatype data)//前面插入数据
{
Node *p1, *p2;
p1 = p2 = NULL;


p1 = pnode;
while (p1 != NULL)//查找结点位置
{
if (p1->num == findnum)
{
//p1保存了要删除结点的地址
break;
}
else
{
p2 = p1;//p2保存上一个结点
p1 = p1->pNext;//循环前移
}
}


Node *pnewnode = (Node *)malloc(sizeof(Node));
pnewnode->data = data;
pnewnode->num = newnum;


if (p1 == pnode)
{
pnewnode->pNext = pnode;
pnode = pnewnode;//头部插入一个结点
}
else
{
pnewnode->pNext = p1;
p2->pNext = pnewnode;
}


return pnode;
}


//冒泡排序:链表需遍历所有数据,不同于数组
void sort(Node *pnode, char ch)
{
if (ch == '<')//从小到大
{
for (Node *p1 = pnode; p1 != NULL; p1 = p1->pNext)
{
for (Node *p2 = pnode; p2 != NULL; p2 = p2->pNext)
{
if (p1->num > p2->num)
{
struct node tnode;
tnode.num = p1->num;
p1->num = p2->num;
p2->num = tnode.num;


tnode.data = p1->data;
p1->data = p2->data;
p2->data = tnode.data;
}
}
}
}


if (ch == '>')//从大到小
{
for (Node *p1 = pnode; p1 != NULL; p1 = p1->pNext)
{
for (Node *p2 = pnode; p2 != NULL; p2 = p2->pNext)
{
if (p1->num < p2->num)
{
struct node tnode;
tnode.num = p1->num;
p1->num = p2->num;
p2->num = tnode.num;


tnode.data = p1->data;
p1->data = p2->data;
p2->data = tnode.data;
}
}
}
}
}





/****************************************************************
*文件名  test..c
*创建者:ycj
*创建时间:2015-3-12
*文件说明:实现单链表:增加,删除,查询,修改,排序,逆转

*****************************************************************/

#include "linknode.h"

#pragma comment(lib, "linknode.lib")//引用静态库


void main()
{
Node *pnode = NULL;//链表的头结点
//backaddnode(&pnode, 1, 10);//增加结点
//backaddnode(&pnode, 2, 11);//增加结点
//backaddnode(&pnode, 3, 12);//增加结点
pnode = backaddnodeA(pnode, 1, 1);
pnode = backaddnodeA(pnode, 22, 11);
pnode = backaddnodeA(pnode, 4, 1111);
pnode = backaddnodeA(pnode, 52, 11111);
pnode = backaddnodeA(pnode, 62, 111111);
showallnode(pnode);//显示所有的结点


printf("change:\n");
change(pnode, 4, 55555);//修改失败返回0,成功返回1
showallnode(pnode);//显示所有的结点


printf("insert:\n");
pnode = insert(pnode, 4, 0, 3333);//前面插入数据
pnode = insert(pnode, 62, 3, 3333);//前面插入数据
showallnode(pnode);//显示所有的结点


printf("sort:\n");
sort(pnode, '<');
showallnode(pnode);//显示所有的结点


printf("rev:\n");
pnode = rev(pnode);//链表的逆转
showallnode(pnode);//显示所有的结点




printf("deletenode:\n");
pnode = deletenode(pnode, 1);//删除
pnode = deletenode(pnode, 4);//删除
pnode = deletenode(pnode, 62);//删除
showallnode(pnode);//显示所有的结点


printf("searchfirst:\n");
Node *pfind = searchfirst(pnode, 22);//查询
if (pfind == NULL)
{
printf("没有找到\n");
}
else
{
printf("%p,%d,%d,%p\n", pfind, pfind->num, pfind->data, pfind->pNext);
}


system("pause");
}












0 0