数据结构-c语言实现链表的创建,增删,翻转

很经典的课题了,这里直接给出源程序:

#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个数字的首地址开始打印的,当然就打印不全了。

猜你喜欢

转载自blog.csdn.net/linzihahaha/article/details/85329786