结构之美:单链表的初始化、创建与遍历

前面已经对单链表做了一些解释。链表在进行循环遍历时效率不高,但是插入和删除时优势明显。

单链表实际上是由节点(Node)组成的,一个链表拥有不定数量的节点。而向外暴露的只有一个头节点(Head),我们对链表的所有操作,都是直接或者间接地通过其头节点来进行的。节点(Node)是由一个需要储存的对象及对下一个节点的引用组成的。也就是说,节点拥有两个成员:储存的对象、对下一个节点的引用。其实应该用数据和地址代替前面的对象和引用的。

单链表的结构示意图(包括空的单链表):

那么大家可能清楚了,为什么说有了头节点就可以操作所有节点。因为有连续不断的引用嘛!那么在链表里的属性大概就只有两个了:头节点和节点数量。当然,根据需要,我们通常需要更多的属性。

下面用C语言简单写一个单链表,并完成初始化,创建链表与链表遍历。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

typedef int ElemType;   /* ElemType类型根据实际情况而定,这里假设为int */
/* 定义单链表结点类型 */
typedef struct Node{
    ElemType element;
    struct Node *next;
}Node;

/* 1.初始化线性表,即置单链表的表头指针为空 */
void initList(Node **pNode)
{
    *pNode = NULL;
    printf("initList函数执行,初始化成功\n");
}

/* 2.创建线性表,此函数输入负数终止读取数据*/
Node *creatList(Node *pHead)
{
    Node *p1;
    Node *p2;

    p1=p2=(Node *)malloc(sizeof(Node)); //申请新节点
    if(p1 == NULL || p2 ==NULL)
    {
        printf("内存分配失败\n");
        exit(0);
    }
    memset(p1,0,sizeof(Node));

    scanf("%d",&p1->element);   //输入新节点
    p1->next = NULL;            //新节点的指针置为空
    while(p1->element > 0)      //输入的值大于0则继续,直到输入的值为负
    {
        if(pHead == NULL)       //空表,接入表头
        {
            pHead = p1;
        }
        else
        {
            p2->next = p1;      //非空表,接入表尾
        }
        p2 = p1;
        p1=(Node *)malloc(sizeof(Node));    //再重申请一个节点
        if(p1 == NULL || p2 ==NULL)
        {
        printf("内存分配失败\n");
        exit(0);
        }
        memset(p1,0,sizeof(Node));
        scanf("%d",&p1->element);
        p1->next = NULL;
    }
    printf("creatList函数执行,链表创建成功\n");
    return pHead;           //返回链表的头指针
}

/* 3.打印链表,链表的遍历*/
void printList(Node *pHead)
{
    if(NULL == pHead)   //链表为空
    {
        printf("PrintList函数执行,链表为空\n");
    }
    else
    {
        while(NULL != pHead)
        {
            printf("%d ",pHead->element);
            pHead = pHead->next;
        }
        printf("\n");
    }
}

int main()
{
    Node *pList = NULL;
    int length = 0;

    ElemType posElem;
    initList(&pList);   //链表初始化
    printList(pList);   //遍历链表,打印链表

    printf("请为链表输入节点值,输入负数退出 \n");
    pList=creatList(pList); //创建链表
    printList(pList);
}

链表是由不定数量的节点连接(通过相互之间的引用)起来的,由于这种关系,在链表里我们只定义了头节点和节点数量。节点是由存储的对象及对下一个“节点”的引用封装而成。

posted on 2014-09-22 22:12  迪迪520  阅读(6428)  评论(0编辑  收藏  举报

导航