我们将复习单链表、静态链表、循环链表和双向链表。

(1)单链表

单链表的数据存放的基本单元是一个Node. 一个Node主要包括数据部分和下一个Node的指针。

struct node
{
   node* next;
   float data;
};

初始化整个链表为:

void InitList(node* &L, int num)
{
    L = (node*)malloc(sizeof(node));    // allocate the momory for head node
    L->next = nullptr;

    node* p,*p0;
    p0 = L;
    for(int i = 0; i<num ; ++i)            // initialize the nodes
    {
        p = (node*)malloc(sizeof(node)); // allocate the memory for each node
        p->data = rand()%100;
        p0->next = p;
        p0 = p;
        listNumber++;
    }

    p->next = nullptr;
};

初始化的输入链表的首地址和初始化Node的个数。我们首先对链表的首个Node进行初始化。这个Node不负责保存数据,只负责保存第一存取Node的地址。 如果我们初始化num个节点,我们需要进行循环,对每个Node进行内存申请,并且对它的Next进行赋值。其中,全局变量listNumber用来统计链表中Node的有效个数。对于尾巴节点的p->next = nullptr。这里的赋值采用rand()%随机数。

删除整个链表

void DeleteList(node* L)
{
    node* p0;
    node* p = L->next;
    while(p != nullptr)
    {
        p0 = p;
        p=p->next;
        free(p0);
    }
    L->next = nullptr;
    listNumber =0;
}

删除所有Node的过程与初始化的类似。唯一要注意的是,循环的过程,取Next的操作要在删除Node的前面,否则会出现错误。这里我们保留了首Node的信息。删除了所有保存Data的Node的信息。注意listNumber的数目要变成0。

添加Node

void InsertNode(node* &L, int ipos, float fdata)
{
    if(ipos <1 || ipos > listNumber){
        std::cout <<"insert wrong ipos"<<std::endl;
        return;
    }
    node* p0;
    node* p = L;

    int i;
    for(i=0;i<ipos && p->next!=nullptr;++i)
    {
        p0 =p;
        p = p->next;
    }
    node* pn = (node*)malloc(sizeof(node)); 
    p0->next = pn;
    pn->data = fdata;
    pn->next = p;
    listNumber++;
}

添加的位置为第ipos个Node,添加的数据为fdata。首先我们需要检查ipos的位置是否在1~listNumber之间,否则会出错。然后找到第ipos-1和ipos的Node的位置。将新插入的Node放在它们之间。并且改变它们之间的链接关系。

删除Node

void DeleteNode( node* &L, int ipos)
{
    if(ipos <1 || ipos > listNumber){
        std::cout <<"delete wrong ipos"<<std::endl;
        return;
    }
    node* p0;
    node* p = L;
    int i;
    for(i=0;i<ipos && p->next!=nullptr;++i)
    {
        p0 =p;
        p = p->next;
    }

    p0->next = p->next;
    free(p);    
    listNumber--;
}

删除第ipos个位置的Node,需要我们找到ipos的Node,然后将ipos-1的Next连接到原来ipos+1的Node上。

 

我们可以采用简单main来验证上面的结果。

void main()
{
    node* List= nullptr;
    InitList(List,5);
    printList(List);

    InsertNode(List,1, 99);
    printList(List);

    InsertNode(List,3, 99);
    printList(List);

    InsertNode(List,5, 99);
    printList(List);

    DeleteNode(List,5);
    printList(List);


    DeleteList(List);
    printList(List);

    return;
}

其中结果如下图:

image

posted on 2013-02-24 10:58  GreenLight  阅读(201)  评论(0)    收藏  举报