/*
*----------------------------
* sinLinkListCRUD.c
* Created on: 2015年8月28日
* Author: leiwei
*----------------------------
*/
#include
#include
#include
typedef struct sinNode {
int data;
struct sinNode* pNext;
} vsinN;
/*
* 申明各个函数接口方便调用
*/
//创建链表接口封装设计
int createSlink(vsinN** pHeadI);
//链表销毁接口封装设计
int destLink(vsinN* pHead);
//链表逆值操作
int sLinkRveser(vsinN* pHead);
//在x节点前插入y接口封装设计
int insertSlink(vsinN* pHead, int x, int y);
//删除数据域内容为x的链表节点接口封装设计
int delSlink(vsinN* pHead, int x);
//打印链表接口封装设计
int printSlink(vsinN* pHead);
/************************+++以下是创建链表+++***************************/
//创建链表
int createSlink(vsinN** pHeadI) { //二级指针做函数参数甩出结果
/*
* 创建单向链表的的思想:
* 1、首相创建头节点
* 2、创一个辅助指针变量,指向这个头结点
* 3、创建新节点指针
* 4、辅助指针变量的指针域指向新创建的节点
* 5、把新节点指针变量赋给辅助指针变量节点变量
*/
int ret = 0; //定义函数返回状态
//初始化链表头结点
vsinN* pHead = NULL;
pHead = (vsinN*) malloc(sizeof(vsinN));
if (pHead == NULL) {
ret = -1;
printf(
"\nerr:Fun-createSlink(vsinN** pHeadI)-(vsinN*)malloc(sizeof(vsinN))");
return ret;
}
memset(pHead, 0, sizeof(vsinN));
pHead->data = 0;
pHead->pNext = NULL;
//循环创建节点,从键盘录入数据,当键盘录入到-1时结束
int tmp = 0;
printf("请输入数据(注:输入-1停止):\n");
fflush(stdout);
scanf("%d", &tmp);
vsinN* pHeadN = NULL; //新创建的节点
vsinN* pCur = NULL; //辅助指针
pCur = pHead;
while (tmp != -1) {
//不断malloc新节点
pHeadN = (vsinN*) malloc(sizeof(vsinN));
if (pHeadN == NULL) {
destLink(pHead); //如果中途创建链表失败那就销毁掉
printf(
"\nerr:fun-createSlink(vsinN** pHeadI)-(vsinN*)malloc(sizeof(vsinN))");
ret = -2;
return ret;
}
memset(pHeadN, 0, sizeof(vsinN));
pHeadN->data = tmp;
pHeadN->pNext = NULL;
//新节点接入链表
pCur->pNext = pHeadN; //因为辅助指针pCur开始是指向头节点的,所以这儿其实相当于头节点的指针域指向下一个节点
pCur = pHeadN;
scanf("%d", &tmp);
}
*pHeadI = pHead;
return ret;
}
/****************************+++以上是创建链表+++*************************************/
/****************************+++以下是打印链表+++*************************************/
//打印链表
int printSlink(vsinN* pHead) {
int ret = 0;
if (pHead == NULL) {
printf("\nerr:pHead==NULL");
ret = -1;
return ret;
}
vsinN* pCur = NULL; //定义辅助指针变量
pCur = pHead->pNext;
while (pCur) {
fflush(stdout);
printf("%d,", pCur->data);
pCur = pCur->pNext;
}
return 0;
}
//在x节点前插入y
int insertSlink(vsinN* pHead, int x, int y) {
int ret = 0;
if (pHead == NULL || x == 0) {
printf("\nerr:pHead==NULL");
ret = -1;
return ret;
}
//需要定义两个辅助指针变量
vsinN* pCur = pHead; //记录头节点
vsinN* pre = pHead->pNext; //记录头节点的下一个节点
while (pre) {
if (pre->data == x) {
//如果找到了重新malloc一个节点
vsinN* newNode = (vsinN*) malloc(sizeof(vsinN));
newNode->data = y;
pCur->pNext = newNode;
newNode->pNext = pre;
break;
}
pCur = pre;
pre = pre->pNext;
}
return 0;
}
/****************************+++以上是打印链表+++*************************************/
/****************************+++以下是删除链表节点+++*************************************/
//删除数据域内容为x的链表节点
int delSlink(vsinN* pHead, int x) {
int ret = 0;
if (pHead == NULL || x == 0) {
printf("\nerr:pHead == NULL");
ret = -1;
return ret;
}
//定义辅助指针变量
vsinN* pre = pHead; //记录头节点
vsinN* pCur = pHead->pNext; //记录头节点的下一个节点
while (pCur) {
if (pCur->data == x) {
break;
}
pre = pCur;
pCur = pCur->pNext;
}
//没找数据与内容为x的节点情况
if (pCur == NULL) {
ret = -2;
printf("\nerr:pCur==NULL");
return ret;
}
pre->pNext = pCur->pNext;
free(pCur);
return 0;
}
/****************************+++以上是删除链表节点+++*************************************/
/****************************+++以下是销毁链表+++*************************************/
//链表销毁
int destLink(vsinN* pHead) {
int ret = 0;
if (pHead == NULL) {
printf("\nerr:pHead==NULL");
ret = -1;
return ret;
}
//辅助指针变量
vsinN* pCur = pHead; //销毁链表一定要从头节点开始销毁
vsinN* tmp = NULL;
while (pCur) {
//因为头节点的指针域记录了下一个节点,所以先用临时变量保存下一个节点
tmp = pCur->pNext;
free(pCur);
pCur = tmp;
}
return ret;
}
/****************************+++以上是销毁链表+++*************************************/
/****************************+++以下是逆值链表+++*************************************/
//链表的逆值操作
int sLinkRveser(vsinN* pHead) {
int ret = 0;
if (pHead == NULL || pHead->pNext == NULL || pHead->pNext->pNext == NULL) {
printf(
"\nerr:fun->sLinkRveser(vsinN* pHead)->(pHead == NULL || pHead->pNext == NULL || pHead->pNext->pNext == NULL)");
ret = -1;
return ret;
}
//定义三个辅助指针变量,根据分析得出,从除去头节点的第二个节点开始逆值为最佳
vsinN* tmp = NULL, *pCur = NULL, *buf = NULL;
tmp = pHead->pNext; //记录第一个业务节点
pCur = tmp->pNext; //记录第二个业务节点
tmp->pNext = NULL; //尾部节点指针域置空
while (pCur != NULL) {
buf = pCur->pNext; //缓存指针变量
//负责改变指针域指向
pCur->pNext = tmp;
//负责指针前移
tmp = pCur;
pCur = buf;
}
//最后再让头节点的指针域指向最后被逆值的节点
pHead->pNext = tmp;//(重要注意点要让头节点指向tmp而不是pCure)
return ret;
}
/****************************+++以上是逆值链表+++*************************************/
void testLink() {
vsinN* sl = NULL;
int ret = createSlink(&sl);
if (ret == 0) {
printf("链表创建成功");
}
//输出链表内容
printf("\n初始化准备之后:\n");
printSlink(sl);
//插入节点
insertSlink(sl, 30, 100);
printf("\n插入节点后:\n");
printSlink(sl);
//删除节点
delSlink(sl, 100);
printf("\n删除节点后:\n");
printSlink(sl);
//逆值链表
sLinkRveser(sl);
printf("\n逆值链表后:\n");
printSlink(sl);
//销毁链表
int result = destLink(sl);
if (result == 0) {
printf("\n链表销毁成功");
}
}