您的位置:首页 > 其它

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

2015-03-13 09:40 639 查看
/****************************************************************

*文件名: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");

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐