#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *pNext;
};
/*
函数名: createNode
函数参数:data--结点的数据元素
函数返回值: 返回堆区创建出来的结点首地址
函数作用: 创建一个新结点
*/
struct node* createNode(int data)
{
struct node *p = (struct node*)malloc(sizeof(struct node));
if(p == NULL)
{
printf("malloc error.\n");
return NULL;
}
//创建成功,初始化该结点
p->pNext = NULL;
p->data = data;
//返回该结点的首地质
return p;
}
/*
函数名: insertNodeToListTail
函数参数:pH--插入哪个一个链表的头指针 new--新创建的结点(由函数createNode创建)
函数返回值: void
函数作用: 在链表的尾部插入一个新结点
*/
void insertNodeToListTail(struct node* pH,struct node* new)
{
struct node*p = pH;
//走到尾结点
while(p->pNext != NULL)
{
p = p->pNext;//第一次近来指向第一个结点(跳过头结点)
}
//到这步时,p指向尾结点
p->pNext = new;
}
/*
函数名: insertNodeToListHead
函数参数:pH--插入哪个一个链表的头指针 new--新创建的结点(由函数createNode创建)
函数返回值: void
函数作用: 在链表的头部插入一个新结点
*/
void insertNodeToListHead(struct node* pH,struct node* new)
{
//新结点指向的下一个结点是原链表的第一个结点
new->pNext = pH->pNext;
//头结点指向的下一个结点是新结点(新结点成为第一个结点)
pH->pNext = new;
}
/*
函数名: deleteNoteToList
函数参数:pH--删除哪个一个链表的头指针 data--要删除的结点中的数据
函数返回值: 删除成功返回0 删除失败返回-1
函数作用: 删除链表中相同数据的结点(只能删除一个)
*/
int deleteNoteToList(struct node* pH,int data)
{
struct node* p = pH;
struct node *pBack = NULL;
while(p->pNext != NULL)
{
pBack = p; //记录要删除的结点的上一个结点
p = p->pNext;
if(p->data == data)
{
pBack->pNext = p->pNext; //要删除结点的上一个结点指向要删除结点的下一个结点(跳过要删除的结点)
free(p); //切记要释放该结点的堆空间
return 0;
}
}
printf("can't find this data,delete error.\n");
return -1;
}
/*
函数名: traversalList
函数参数:pH--遍历哪个一个链表的头指针
函数返回值: void
函数作用: 遍历链表
*/
void traversalList(struct node *pH)
{
struct node *p =pH;
while(p->pNext != NULL)
{
p = p->pNext;//第一次执行完之后,p跳过头结点,指向第一个结点
printf("node data: %d\n",p->data);
}
}
/*
函数名: reverseNodeToList
函数参数:pH--逆序哪个一个链表的头指针
函数返回值: void
函数作用: 逆序链表
将链表中的结点挨个头插入
*/
void reverseNodeToList(struct node *pH)
{
struct node *p = pH->pNext; //这里需要直接指向第一个结点
struct node *pBack = NULL;
if((p == NULL)||(p->pNext == NULL)) //没有有效结点或者只有一个结点时,不需要做任何操作
return ;
while(p->pNext != NULL)
{
pBack = p->pNext; //记录p的下一个结点,否则等下p插入之后,无法找到p的下一个结点
if(p == pH->pNext) //原链表中的第一个有效结点在逆序之后为尾结点,其pNext应该指向NULL
{
p->pNext = NULL;
}
else
{
p->pNext = pH->pNext;
}
pH->pNext = p;
p = pBack; //插入完成之后,应该跳转到原来该结点指向的下一个结点
}
//走到这一步的时候,原来的尾结点由于不符合whlie的条件并没有插入,因此需要手动插入
insertNodeToListHead(pH,p);
}
int main(int argc, char **argv)
{
//头指针指向头结点,一般情况下,头结点中的数据记录了链表的相关信息而不是数据元素
struct node *pHeader = createNode(0); //头结点的生成方式与普通结点生成方式不太一样
insertNodeToListTail(pHeader,createNode(10));
insertNodeToListTail(pHeader,createNode(20));
insertNodeToListTail(pHeader,createNode(30));
insertNodeToListTail(pHeader,createNode(40));
insertNodeToListTail(pHeader,createNode(50));
//deleteNoteToList(pHeader,3);
reverseNodeToList(pHeader);
traversalList(pHeader);
return 0;
}