逻辑结构:线性结构 树形结构 图状结构
存储结构:顺序存储 链式存储
顺序表
存储在连续的的空间中(数组),因此每个元素的存储位置可用一个简单的公式计算得到,所以访问表中某个元素的效率是很高的,但是顺序表是连续的,就会带来一个问题:如果对某一顺序表进行插入和删除操作,为了保持元素存储区域的连续性,必须移动大量的元素:
1.插入:需要后移若干元素给新元素腾位置,从末尾元素开始向前直到插入位置为止,依次将每个元素向后移动一个位置
2.删除:从删除的位置后的第一个元素开始,依次向前移一个位置,此时删除位置已经被覆盖删除
单链表
用一组地址任意的存储单元存放线性表中的数据元素,逻辑上相邻的元素物理位置不一定相邻。
为了建立元素间的逻辑关系,需要在线性表的每个元素中附加其后继元素的地址信息:指针
附加了其他元素指针的数据元素称为结点,每个结点都包含数据域和指针域
typedef struct NODE
{
datatype data;
Node* next;
}Node;
这个定义是自引用类型:每个结点都包含另一个同类型结点的地址
不同结点的存储位置是分散的,但每个结点所包含的数据项却是存放在一小块连续的空间中
结点的指针存放的指针存放的就是整个结点所占空间的起始地址
单链表第一个结点的存储地址就是就是线性表的头指针head
头结点的数据域为空,增加头结点是避免在对第一个元素进行操作时出现问题
在定义一个带头结点的单链表时,只需定义头指针和一个头结点即可
定义头指针
Node* head;
定义头结点
head=(Node*)malloc(sizeof(Node));
头结点的指针域为空
head->next=NULL;
#include<stdlib.h>
#include<stdio.h>
#include<iostream>
using namespace std;
typedef int DataType;
typedef struct NODE Node;
typedef struct NODE
{
DataType data;
Node* next;
}Node;
typedef Node* Head;
int GetLinkLength(Head head)
{
if (head == NULL)
{
return 0;
}
int i = i;
Node* pNode = head;
while (pNode->next)
{
i++;
pNode = pNode->next;
}
return i;
}
void DestoryLink(Head head)
{
Node* pNode;
while (head)
{
pNode = head;
head = head->next;
free(pNode);
}
}
int GetElement(Head head, int n, DataType* data)
{
if (n<0 || n>GetLinkLength(head) - 1)
{
return 0;
}
Node* pNode = head;
for (int i = 0; i < n; i++)
{
pNode = pNode->next;
}
*data = head->data;
return 1;
}
int FindElement(Head head, DataType data)
{
int i = 0;
Node* pNode = head;
while (pNode != NULL)
{
if (pNode->data == data)
{
return i;
}
pNode=pNode->next;
i++;
}
return -1;
}
int GetPriorElement(Head head, int n, DataType* data)
{
if (n<1 || n>GetLinkLength(head) - 1)
{
return -1;
}
Node* pNode = head;
for (int i = 0; i < n - 1; i++)
{
pNode = pNode->next;
}
*data = head->data;
return n - 1;
}
int GetNextElement(Head head, int n, DataType* data)
{
if (n<0 || n>GetLinkLength(head) - 2)
return -1;
Node* pNode = head;
for (int i = 0; i < n + 1; i++)
{
pNode = pNode->next;
}
*data = head->data;
return n + 1;
}
int InsertToList(Head* head, int pos, DataType data)
{
Node* pNode = *head;
int length = GetLinkLength(pNode);
if (pos<0 || pos>length)
return -1;
if (pos == 0)
{
return InsertHead(head, data);
}
if (pos == length - 1)
{
return InsertRear(head, data);
}
for (int i = 0; i < pos - 1; i++)
{
pNode = pNode->next;
}
Node* pNewNode = (Node*)malloc(sizeof(Node));
if (pNewNode == NULL)
return -1;
pNewNode->data = data;
pNewNode->next = pNode->next;
pNode->next = pNewNode;
length = length + 1;
return length;
}
int DeleteFromList(Head* head, int pos)
{
Node* pNode = *head;
int length = GetLinkLength(*head);
if (pos<0 || pos>length - 1)
return -1;
Node* pDeleteNode;
if (pos > 0)
{
for (int i = 0; i < pos - 1; i++)
{
pNode = pNode->next;
}
pDeleteNode = pNode->next;
pNode->next = pNode->next->next;
}
if (pos == 0)
{
pDeleteNode = *head;
*head = (*head)->next;
}
free(pDeleteNode);
length = length - 1;
return length;
}