很经典的课题了,这里直接给出源程序:
#include <stdio.h>
#include <stdlib.h>
#define LIST_MAX_LEN 10
typedef int ElementType;
typedef int BOOL;
#define TRUE 1
#define FALSE 0
typedef struct node
{
ElementType data;
struct node *next;
}Node,*pNode;
void InitNode(pNode pl)
{
if (pl==NULL)
{
return;
}
pl->next=NULL;
}
pNode TraverseList(pNode pl,int num)
{
printf("遍历链表:\n");
int index=0;
pNode temp=(pNode)malloc(sizeof(Node));
if (temp==NULL)
{
return pl;
}else
{
temp=pl->next;
}
while(temp!=NULL && (index<num))
{
printf("%d\t",temp->data);
temp=temp->next;
index++;
}
printf("\n");
return temp;
}
void CreateList(pNode pl ,int num)
{
if (num<=0)
{
return;
}
printf("开始创建链表:\n");
for (int i=0;i<num;i++)
{
pNode new = (pNode)malloc(sizeof(Node));
if (new==NULL)
{
return;
}
new->data=i;
new->next=pl->next;
pl->next=new;
}
printf("address pl=%d",pl);
printf("链表创建成功。\n");
}
BOOL InsertList(pNode pl,int num,int index,int *list_len)
{
if (index >=*list_len)
{
printf("插入的位置超过链表最大长度\n");
return FALSE;
}
pNode node_index = (pNode)malloc(sizeof(Node));
if (node_index==NULL) return FALSE;
if (index==0)//在表头插入
{
node_index=pl;
} else
{
//遍历到指定index 的位置的上一个位置
node_index = TraverseList(pl,index-1);
}
//创建新节点
pNode new= (pNode)malloc(sizeof(Node));
if (new==NULL) return FALSE;
//插入新节点
new->data=num;
new->next=node_index->next;
node_index->next=new;
// printf("node_index:data:%d\n",node_index->data);
(*list_len)+=1;
return TRUE;
}
BOOL DeleteList(pNode pl,int index,int *list_len)
{
if (index >=*list_len)
{
printf("删除的位置超过链表最大长度\n");
return FALSE;
}
pNode node_index = (pNode)malloc(sizeof(Node));
if (node_index==NULL) return FALSE;
if (index==0)//在表头删除
{
node_index=pl;
} else
{
//遍历到指定index 的位置的上一个位置
node_index = TraverseList(pl,index-1);
}
//删除节点
node_index->next=node_index->next->next;
//free(node_index->next);
//node_index==NULL;
// printf("node_index:data:%d\n",node_index->data);
(*list_len)+=1;
return TRUE;
}
BOOL ReversalList(pNode pl,int list_len)
{
pNode before_node=pl;
if (list_len<=1)
{
printf("链表为空或长度为1\n");
return TRUE;
}
before_node=before_node->next;
pNode next_node=before_node->next;//记下第一个节点的下一个节点
before_node->next=NULL;//让第一个节点变成尾节点
pNode current_node= next_node;//第一个节点处理完毕,下一个节点成为当前节点
while(current_node!=NULL)
{
next_node=current_node->next;//记下下一个节点
current_node->next=before_node;//当前节点指向上一个节点
//为下一循环准备
before_node=current_node;//上一个节点变成当前节点
//printf("data:%d\n",before_node->data);
current_node=next_node;//下一节点变成当前节点
}
pl->next=before_node;
//TraverseList(pl,list_len);
return TRUE;
}
int main()
{
//printf("Hello world!\n");
int insert_num= 0;
int index=0;
int list_length =LIST_MAX_LEN;
pNode pl=(pNode)malloc(sizeof(Node));
InitNode(pl);
printf("address pl=%d",pl);
//创建链表
CreateList(pl,list_length);
//遍历链表
TraverseList(pl,list_length);
//翻转链表
if(ReversalList(pl,list_length))
{
printf("翻转成功\n");
//遍历链表
TraverseList(pl,list_length);
}
//插入链表,并修改链表长度
printf("请输入插入的数字即位置:\n");
scanf("%d%d",&insert_num,&index);
if (InsertList(pl,insert_num,index,&list_length))
{
printf("插入成功\n");
//遍历链表
TraverseList(pl,list_length);
}
//删除链表,并修改链表长度
printf("请输入删除的位置:\n");
scanf("%d",&index);
if (DeleteList(pl,index,&list_length))
{
printf("删除成功\n");
//遍历链表
TraverseList(pl,list_length);
}
return 0;
}
说下我碰到的问题:
在翻转的时候,一开始我的程序是直接把形参里的pl 带入到while 循环里去各种替换,然后发现打出的结果不对了:
BOOL ReversalList(pNode pl,int list_len)
{
if (list_len<=1)
{
printf("链表为空或长度为1\n");
return TRUE;
}
pl=pl->next;
pNode next_node=pl->next;//记下第一个节点的下一个节点
pl->next=NULL;//让第一个节点变成尾节点
pNode current_node= next_node;//第一个节点处理完毕,下一个节点成为当前节点
while(current_node!=NULL)
{
next_node=current_node->next;//记下下一个节点
current_node->next=pl;//当前节点指向上一个节点
//为下一循环准备
pl=current_node;//上一个节点变成当前节点
printf("data:%d\n",pl->data);
current_node=next_node;//下一节点变成当前节点
}
printf("address pl=%d",pl);
//新建一个头结点,并指向pl。
pNode top=(pNode)malloc(sizeof(Node));
if (top==NULL) return FALSE;
top->next=pl;
pl=top;
printf("address pl=%d",pl);
TraverseList(pl,list_len);
return TRUE;
}
结果如下:
结果可以看到,在 main 函数里。,打出的pl的首地址跟在reversalList 函数里打出的首地址一样了,所以在调用函数里能打出链表的所有值,而 main函数里再去打印时,却是从第9个数字的首地址开始打印的,当然就打印不全了。