c/c++常用算法(2) -- 数据结构(线性表的链式存储)

来源:互联网 发布:华东师范大学网络研修 编辑:程序博客网 时间:2024/05/16 07:07

一、线性表的链式存储结构


      链式存储:用一组任意的存储单元存储线性表中的数据元素。用这种方法存储的线性表简称线性链表

      存储链表中结点的一组任意的存储单元可以是连续的,也可以是不连续的,甚至是零散分布在内存中的任意位置上的。

      链表中结点的逻辑顺序和物理顺序不一定相同。

      为了正确表示结点间的逻辑关系,在存储每个结点值的同时,还必须存储指示其直接后继结点的地址(或位置),称为指针(pointer)或链(link),这两部分组成了链表中的结点结构,如图2-2所示。


data :数据域,存放结点的值

                       next:指针域,存放结点的直接后继的地址


      表是通过每个结点的指针域将线性表的n个结点按其逻辑次序链接在一起的。

      每一个结只包含一个指针域的链表,称为单链表。

      为操作方便,总是在链表的第一个结点之前附设一个头结点(头指针)head指向第一个结点。头结点的数据域可以不存储任何信息(或链表长度等信息)。


二、结点描述与实现


1 .描述


      C语言中用带指针的结构体类型来描述

typedef  struct  Lnode{   ElemType  data;     /*数据域,保存结点的值 */    struct   Lnode  *next;      /*指针域*/}LNode;        /*结点的类型 */

2.实现


      结点是通过动态分配和释放来的实现,即需要时分配,不需要时释放。实现时是分别使用C语言提供的标准函数:malloc(),realloc(),sizeof(),free() 。


      动态分配  p=(LNode*)malloc(sizeof(LNode));

      函数malloc分配了一个类型为LNode的结点变量的空间,并将其首地址放入指针变量p中。


      动态释放  free(p);

      系统回收由指针变量p所指向的内存区。P必须是最近一次调用malloc函数时的返回值。


3.代码:


List.h

#ifndef __CHelloWorld__List__#define __CHelloWorld__List__#include <iostream>using namespace std;typedef struct{    char key[10];   //结点的关键字    char name[20];    int age;}Data;              //结点类型typedef struct Node     //定义链表结构{    Data nodeData;    struct Node *nextNode;}CLType;class List{public:    CLType *CLAddEnd(CLType* head,Data nodeData);   //追加结点(链表尾增加结点)    CLType *CLAddFirst(CLType* head,Data nodeData); //插入头结点    CLType *CLFindNode(CLType* head,char *key);     //查找结点    CLType *CLInsetNode(CLType* head,char *findkey,Data nodeData);//插入结点    int CLDeleteNode(CLType* head,char *key);       //删除结点    int CLLength(CLType* head);                     //计算链表长度    void CLAllNode(CLType *head);                   //遍历链表};#endif /* defined(__CHelloWorld__List__) */
List.cpp

#include "List.h"CLType *List::CLAddEnd(CLType *head, Data nodeData){    CLType *node;    CLType *htemp;    if (!(node = (CLType*)malloc(sizeof(CLType))))    {        cout<<"申请内存失败!"<<endl;        return NULL;    }    else    {        node->nodeData = nodeData;        node->nextNode = NULL;        if (head == NULL)        {            head = node;            return head;        }        htemp = head;        while (htemp->nextNode != NULL)        {            htemp = htemp->nextNode;        }        htemp->nextNode = node;        return head;    }}CLType *List::CLAddFirst(CLType *head, Data nodeData){    CLType *node;    if (!(node = (CLType*)malloc(sizeof(CLType))))    {        cout<<"申请内存失败!"<<endl;        return NULL;    }    else    {        node->nodeData = nodeData;        node->nextNode = head;        head = node;        return head;    }}CLType *List::CLFindNode(CLType *head, char *key){    CLType *htemp;    htemp = head;    while (htemp)    {        if (strcmp(htemp->nodeData.key, key) == 0)        {            return htemp;        }        htemp = htemp->nextNode;    }    return NULL;}CLType *List::CLInsetNode(CLType *head ,char *findkey, Data nodeData){    CLType *node,*nodetemp;    if (!(node = (CLType*)malloc(sizeof(CLType))))    {        cout<<"申请内存失败!"<<endl;        return NULL;    }    node->nodeData = nodeData;    nodetemp = CLFindNode(head, findkey);    if (nodetemp)    {        node->nextNode = nodetemp->nextNode;        nodetemp->nextNode = node;    }    else    {        cout<<"未找到正确的插入位置!"<<endl;        free(node);    }    return head;}int List::CLDeleteNode(CLType *head, char *key){    CLType *node,*htemp;    htemp = head;    node = head;    while (htemp)    {        if (strcmp(htemp->nodeData.key, key) == 0)        {            node->nextNode = htemp->nextNode;            free(htemp);            return 1;        }        else        {            node = htemp;            htemp = htemp->nextNode;        }    }    return 0;}int List::CLLength(CLType *head){    CLType *htemp;    int Len = 0;    htemp = head;    while (htemp)    {        Len++;        htemp = htemp->nextNode;    }    return Len;}void List::CLAllNode(CLType *head){    CLType *htemp;    Data nodeData;    htemp = head;    printf("当前链共有%d个结点。链表所有数据如下:\n",CLLength(head));    while (htemp)    {        nodeData = htemp->nodeData;        printf("结点(%s,%s,%d)\n",nodeData.key,nodeData.name,nodeData.age);        htemp = htemp->nextNode;    }}
main.cpp

#include <iostream>#include "List.h"using namespace std;int main(int argc, const char * argv[]){    CLType *node,*head = NULL;    Data nodeData;    char key[10],findkey[10];    List *mylist = new List();    std::cout << "链表操作演示\n";    do    {        std::cout << "输入添加的结点(学号 姓名 年龄):";        fflush(stdin);  //清空输入缓冲区        scanf("%s",nodeData.key);        if (strcmp(nodeData.key, "0") == 0)   //年龄不能为0        {          break;        }        else        {            scanf("%s%d",nodeData.name,&nodeData.age);            head = mylist->CLAddEnd(head,nodeData);        }    } while (1);        mylist->CLAllNode(head);        std::cout << "\n要插入结点:";    scanf("%s",&findkey);    std::cout << "输入插入结点的数据(学号 姓名 年龄):\n";    scanf("%s%s%d",nodeData.key,nodeData.name,&nodeData.age);    head = mylist->CLInsetNode(head, findkey, nodeData);    mylist->CLAllNode(head);        std::cout << "\n要删除结点:";    scanf("%s",key);    mylist->CLDeleteNode(head, key);    mylist->CLAllNode(head);        std::cout << "\n演示在链表中查找,输入查找关键字:";    fflush(stdin);    scanf("%s",key);    node = mylist->CLFindNode(head, key);    if (node)    {        nodeData = node->nodeData;        scanf("关键字%s对应的结点为(%s,%s,%d)",key,nodeData.key,nodeData.name,&nodeData.age);    }    else    {        printf("在链表中未找到关键字为%s的结点!\n",key);    }        delete mylist;    // insert code here...   // std::cout << "Hello, World!\n";    return 0;}

演示效果图:


            


参考书籍:《C/C++常用算法手册》  《数据结构-清华大学严蔚敏》

0 0
原创粉丝点击