1 线性表(list):由零个或多个数据元素组成的有序序列(第一个元素无前驱,最后一个元素无后继,中间的元素有且仅有一个前驱和后继)
1.1 线性表的顺序存储结构
实现两个线性表A,B的并集操作即使得A=AUB
/*La表示A集合,Lb表示B集合*(C语言实现)/
void unionL(List *La,list Lb)
{
i
ElemType e;
La_len = ListLength(*La);
Lb_len = ListLength(Lb);
for(i=1;i<=Lb_len;i++)
{
GetElem(Lb,i,&e);
if(!LocateElem(*La,e))
{
ListInsert(La,++La_len,e);
}
}
}
/*******************getElem.c*********************/
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int Status;
//Status 是函数的类型,其值是函数结果状态代码,如OK等
//初始条件:顺序线性表L已经存在,1 <= i <=ListLength(L)
//操作结果:用e返回L中第i个数据元素的值
Status GetElem(SpList L,int i,ElemType *e)
{
if(L.length==0||i<1||i>L.length)
{
return ERROR;
}
*e = L.data[i-1];
return OK;
}
/****************************ListInsert.c********************************/
Status ListInsert(SpList *L,int i,ElemType e)
{
if(L.length==MAXSIZE||i<1||i>L.length+1)//顺序表满了或者i不在范围内时
{
return ERROR;
}
if(i<=L->length)//如插入的数据位置不在表尾
{
/*将要插入位置后数据元素想后移动一位*/
for(int k=L->length-1;k>=i-1;k--)//????
{
L->data[k+1] = L->data[k];
}
}
L->data[i-1]=e;
L->length++;
return OK;
}
/**********************************ListDelete.c***********************************/
ListDelete(SpList *L,int i ,ElemType *e)
{
if(L->length==0)//空队列
{
return ERROR;
}
if(L->length<1||L->length+1)//i不在范围内
{
return ERROR;
}
if(i<L->length)//删除的元素后面的元素全部往前移动一位
{
for(int k=i; k<L->length;k++)//????
{
L->data[k-1]=L->data[k];
}
}
*e=L->data[i-1];
L->length--;
return OK;
}
删除和插入的事件复杂度
最好的情况:刚好在线性表最后一个O(1)
最坏的情况:刚好在线性表的第一个O(n)
平均值:O((n-1)/2)=O(n)
结论:线性表的顺序存储结构,在存,读数据时,不管是哪个位置,事件复杂度都是O(1);在插入或者删除时,事件复杂度都是O(n)。
1.2 线性表的链式存储结构
单链表C++实现代码
/*****************Node.h****************************/
#pragma once
#include"Person.h"
class Node
{
public :
Person data;
Node *next;
void printNode();
};
/*********************Node.cpp*************************/
#include "Node.h"
#include<iostream>
#include"Person.h"
using namespace std;
void Node::printNode()
{
cout << data << endl;
}
/*******************List.h***************************/
#pragma once
#include<iostream>
#include"Node.h"
using namespace std;
class List
{
public:
List();
~List();
void ClearList(); //清空线性表
bool ListEmpty(); //判断线性表是否为空
int ListLength(); //获取线性表的长度
bool GetElem(int i,Node *pNode); //获取指定元素
int LocateElem(Node *pNode); //寻找第一个满足e的数据元素的位序
bool PriorElem(Node *currentElem, Node *preElem); //获取指定元素的前驱
bool NextElem(Node *currentElem, Node *nextElem); //获取指定元素的后驱
bool ListInsert(int i, Node *pNode); //在第i个位置插入元素
bool ListDelete(int i, Node *pNode); //在删除第i个位置的元素
void ListTraverse(); //遍历线性表
bool ListInsertHead(Node *pNode); //头插法
bool ListInsertTail(Node *pNode); //尾插法
private:
int m_iLength;
Node *m_pList;
};
/**************************************List.cpp*********************************/
#include "List.h"
#include"Node.h"
#include <iostream>
using namespace std;
List::List()
{
m_pList = new Node;
//m_pList->data = 0; //头结点 数据域没有意义
m_pList->next = NULL;
m_iLength = 0;
}
List::~List()
{
ClearList();
delete m_pList;
m_pList = NULL;
}
bool List::ListInsertHead(Node *pNode) //头插法:将一个节点插入到头结点的后面
{
Node *temp = m_pList->next; //申请一个零时内存来存放头结点的头指针,必须从堆中申请内存,从栈中申请的话,这个函数用完后就会被回收
Node *newNode = new Node; //申请一个节点来存放要插入的节点
if (newNode == NULL)
{
return false;
}
newNode->data = pNode->data;
m_pList->next = newNode;
newNode->next = temp; //新节点尾部指向NULL
m_iLength++;
return true;
}
bool List::ListInsertTail(Node *pNode) //尾插法将新节点插入到list的尾部
{
Node *currentNode = m_pList;
while (currentNode->next!=NULL)
{
currentNode = currentNode->next;
}
Node *newNode = new Node;
if (newNode == NULL)
{
return false;
}
newNode->data = pNode->data;
newNode->next = NULL;
currentNode->next = newNode;
m_iLength++;
return true;
}
void List::ClearList() //清空线性表
{
Node *currentNode = m_pList->next; //currentNode获取头结点所指的下一位
while (currentNode != NULL)
{
Node *temp = currentNode->next; //
delete currentNode;
currentNode = temp;
}
m_pList->next = NULL;
}
bool List::ListEmpty() //判断线性表是否为空
{
return m_iLength == 0 ? true : false;
}
int List::ListLength() //获取线性表的长度
{
return m_iLength;
}
bool List::GetElem(int i, Node *pNode) //获取指定元素
{
if (i < 0 || i >= m_iLength)
{
return false;
}
Node *currentNode = m_pList; //currentNode 赋值为头结点
//Node *currentNodeBefore = NULL;
for (int k = 0; k <= i; k++)
{
//currentNodeBefore = currentNode;
currentNode = currentNode->next;
}
pNode->data = currentNode->data;
return true;
}
int List::LocateElem(Node *pNode) //寻找第一个满足e的数据元素的位序
{
Node *currentNode = m_pList;
int count = 0;
while (currentNode!=NULL)
{
currentNode = currentNode->next;
if (currentNode->data == pNode->data)
{
return count;
}
count++;
}
return -1;
}
bool List::PriorElem(Node *pCurrentNode, Node *pPreNode) //获取指定元素的前驱
{
Node *currentNode = m_pList;
Node *tempNode = NULL;
while (currentNode != NULL)
{
tempNode = currentNode;
currentNode = currentNode->next;
if (currentNode->data == pCurrentNode->data)
{
if (tempNode == m_pList)
{
return false;
}
pPreNode->data = tempNode->data;
}
return true;
}
return false;
}
bool List::NextElem(Node *pCurrentNode, Node *pNextNode) //获取指定元素的后驱
{
Node *currentNode = m_pList;
while (currentNode != NULL)
{
currentNode = currentNode->next;
if (currentNode->data == pCurrentNode->data)
{
if (currentNode == m_pList)
{
return false;
}
pNextNode->data = currentNode->next->data;
}
return true;
}
return false;
}
bool List::ListInsert(int i, Node *pNode) //在第i个位置插入元素
{
if (i<0 || i>m_iLength)
{
return false;
}
Node *currentNode = m_pList;
for (int k = 0; k < i; k++)
{
currentNode = currentNode->next;
}
Node *newNode = new Node;
if(newNode==NULL)
{
return false;
}
newNode->data = pNode->data;
newNode->next = currentNode->next;
currentNode->next = newNode;
return true;
}
bool List::ListDelete(int i, Node *pNode) //在删除第i个位置的元素,并把删除元素的值通过pNode返回出来
{
if (i < 0 || i >= m_iLength)
{
return false;
}
Node *currentNode = m_pList;
Node *currentNodeBefore = NULL;
for (int k = 0; k <= i; k++)
{
currentNodeBefore = currentNode;
currentNode = currentNode->next; //循环结束:currentNode为待删除的节点,currentNodeBefore为待删除节点的前一位
}
currentNodeBefore->next = currentNode->next; //currentNodeBefore指向删除节点后的节点
pNode->data = currentNode->data;
delete currentNode; //删除节点
currentNode = NULL;
m_iLength--;
return true;
}
void List::ListTraverse() //遍历线性表s
{
Node *currentNode = m_pList;
while (currentNode->next != NULL)
{
currentNode = currentNode->next;
currentNode->printNode();
}
}
/***************person.h***********/
#pragma once
#include<string>
using namespace std;
class Person
{
friend ostream &operator<<(ostream &out,Person &person);
public:
string name;
string phone;
Person &operator=(Person &person);
bool operator==(Person &person);
};
/******************person.cpp******************/
#include"Person.h"
Person &Person::operator=(Person &person)
{
name = person.name;
phone = person.phone;
return *this;
}
bool Person :: operator==(Person &person)
{
if (this->name == person.name&&this->phone == person.phone)
{
return true;
}
return false;
}
ostream &operator<<(ostream &out, Person &person)
{
out << person.name << "---------" << person.phone << endl;
return out;
}
/**************************demo.cpp****************************/
#pragma once
#include"List.h"
#include"Node.h"
#include <iostream>
int main(void)
{
Node node1;
Node node2;
node1.data .name= "test";
node1.data.phone = "123456";
node2.data.name = "test1";
node2.data.phone = "12345697";
List *pList = new List();
//pList->ListInsert(0,&node1);
pList->ListInsertHead(&node1);
pList->ListInsertHead(&node2);
pList->ListTraverse();
delete pList;
pList = NULL;
system("pause");
return 0;
}