您的位置:首页 > 理论基础 > 数据结构算法

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

2013-12-19 14:44 459 查看

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

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

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

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

      为了正确表示结点间的逻辑关系,在存储每个结点值的同时,还必须存储指示其直接后继结点的地址(或位置),称为指针(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++常用算法手册》  《数据结构-清华大学严蔚敏》
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c++ 数据结构