线性表的相关算法总结

顺序表的操作

1. 顺序表的存储结构定义

#define MAXSIZE 100
typedef int ElemType;

typedef struct
{
	ElemType *elem;		//存储空间基址
	int length;			//表长
}SqList;

2. 初始化顺序表

void InitList_Sq(SqList &L)
{
	//构造一个空的顺序表L。
	L.elem = new ElemType[MAXSIZE];
	if(!L.elem)
		exit(OVERFLOW); 	// 存储分配失败
	L.length = 0;			// 空表长度为0
}

3. 销毁顺序表

void DestroyList(SqList &L)
{
	if(L.elem)
		delete(L.elem);		//释放存储空间
	L.length = 0;
	L.elem = NULL;
}

4. 清空顺序表

void ClearList(SqList &L)
{
	L.length = 0;		//将线性表的长度置为0
}

5. 求顺序表的长度

int GetLength(SqList L)
{
	return L.length;
}

6. 判断顺序表是否为空

bool IsEmpty(SqList L)
{
	if(L.length == 0)
		return true;
	else
		return false;
}

7. 获取顺序表中的某个位置数据元素内容

时间复杂度为O(1)

void GetElem(SqList L,int i,ElemType &e)
{
	if(i<1 || i>L.length)	//判断i值是否合理,若不合理,返回ERROR
		return ERROR;
	e = L.elem[i-1];     //i是元素在表中的位置
}

8. 在顺序表中查找值为e的数据元素

时间复杂度为O(n)

int LocateElem(SqList L,ElemType e)
{
	for(int i=0;i<L.length;i++)
		if(L.elem[i] == e)
			return i+1;		//i是存储单元的位置
	return 0;
}

9. 在顺序表中插入一个数据元素

时间复杂度为O(n)

void ListInsert_Sq(SqList &L,int i,ElemType e)
{
	if(i<1 || i>L.length+1)		//判断插入位置是否合法
		return ERROR;
	if(L.length == MAXSIZE) 	//当前存储空间是否已满
		return ERROR;
	for(int j = L.length-1;j>=i-1;j--)		//将元素后移
		L.elem[j+1] = L.elem[j];
	L.elem[i-1] = e;
	++L.length;
}

10. 删除顺序表中的第i个数据元素

时间复杂度为O(n)

void ListDelete_Sq(SqList &L,int i)
{
	if(i<1 || i>L.length)		//判断插入位置是否合法
		return ERROR;
	for(int j=i-1;j<L.length;j++)		//将元素前移
		L.elem[j] = L.elem[j+1];
	--L.lehgth;
}

链表的操作

1. 单链表的存储结构定义

typedef struct LNode
{
	ElemType data;			//数据域
	struct LNnode *next;	//指针域
}LNode,*LinkList;			//LinkList为LNode类型的指针

2. 初始化单链表

void InitList_L(LinkList &L)
{
	L = new LNode;
	L->next = NULL;
}

3. 销毁单链表

void DestroyList_L(LinkList &L)
{
	LinkList p;
	while(p)
	{
		p = L;
		L = L->next;
		delete p;
	}
}

4. 清空单链表

void ClearList(LinkList &L)
{
	LinkList p,q;
	p = L->next;
	while(p)			//没到表尾 
	{
		q = p->next;	//p指向第一个结点
		delete p;
		p = q;
	}
	L->next = NULL;		//头结点指针域为空 
}

5. 求单链表的长度

int ListLength_L(LinkList L)
{
	LinkList p;
	p = L->next;
	count = 0;
	//遍历单链表,统计结点数
	while(p)
	{
		++count;
		p = p->next;
	}
	return count;
}

6. 判断单链表是否为空

bool ListEmpty(LinkList L)
{
	if(L->next)
		return true;
	else
		return false;
}

7. 获取单链表中的某个数据元素内容

时间复杂度为O(n)

//获取第i个位置的元素
void GetElem_L(LinkList L,int i,ElemType &e)
{
	LinkList p = L->next;
	int j = 1; 
	//向后扫描,直到p指向第i个元素或p为空 
	while(p && j<i)
	{
		p = p->next;
		++j;
	}
	if(!p || j>i)			//第i个元素不存在 
		return ERROR;
	e = p->data;			//取第i个元素 
}

8. 检索值为e的数据元素

LNode *LocateElem_L(LinkList L,ElemType e)
{
	p = L->next;
	while(p && p->data != e)
		p = p->next;
	//返回L中值为e的数据元素的位置,查找失败返回NULL 
	return p;				
}

9. 在单链表中插入一个数据元素

时间复杂度为O(1)

void ListInsert_L(LinkList L,int i,ElemType e)
{
	p = L;
	j = 0;
	//寻找第i−1个结点 
	while(p && j<i-1)
	{
		p = p->next;
		++j;
	}
	//i大于表长 + 1或者小于1  
	if(!p || j>i-1)
		return ERROR;
	//生成新结点*s 
	s = new LNode;
	s->data = e;           //将结点*s的数据域置为e 
	s->next = p->next;	   //将结点*s插入L中 
	p->next = s;
}

10. 删除单链表中第i个数据

时间复杂度为O(1)

void ListDelete_L(LinkList L,int i,ElemType &e)
{
	p = L;
	j = 0;
	//寻找第i个结点,并令p指向其前驱 
	while(p->next && j<i-1)
	{
		p = p->next;
		++j;
	}
	//删除位置不合理 
	if(!p->next || j>i-1)
		return ERROR;
	//临时保存被删结点的地址以备释放 
	r = p->next;
	//改变删除结点前驱结点的指针域 
	p->next = r->next;
	e = r->data;
	//释放结点 
	delete r;
}

11. 单链表的建立

//前插法
void CreateList_H(LinkList &L,int n)
{
	L = new LNode;
	L->next = NULL;			//先建立一个带头结点的单链表 
	for(int i=n;i>0;i--)
	{
		p = new LNode;		//生成新结点 
		cin >> p->data;
		p->next = L->next;
		L->next = p;		//插入到表头 
	}
}
//后插法
//正位序输入n个元素的值,建立带表头结点的单链表L 
void GreateList_R(LinkList &L,int n)
{
	L = new LNode;
	L->next = NULL;
	r = L;				//尾指针r指向头结点 
	for(int i=0;i<n;i++)
	{
		p = new LNode;	//生成新结点 
		cin >> p->data;
		p->next = NULL;
		r->next = p;		//插入到表尾 
		r = p;				//r指向新的尾结点 
	}
}

线性表的应用

1. 线性表的合并

void union(List &La,List &Lb)
{
	La_len = ListLength(La);		//线性表La的长度
	Lb_len = ListLength(Lb);		//线性表Lb的长度
	for(int i=1;i<=La_length;i++)
	{
		GetElem(Lb,i,e);			// 取Lb中第i个数据元素赋给e
		// La中不存在和 e 相同的数据元素,则插入之
		if(!LocateElem(La,e))
			ListInsert(La,++La_len,e);
	}
}

2. 链式有序表的合并

//按值排序的单链表LA,LB,归并为LC后也按值排序
void MergeList_L(LinkList &La,LinkList &Lb,LinkList &Lc)
{
	//初始化  
	pa = La->next;
	pb = Lb->next;
	Lc = pc = La;
	//将pa 、pb结点按大小依次插入C中
	while(pa && pb)
	{
		if(pa->data <= pb->data)
		{
			pc->next = pa;
			pc = pa;
			pa = pa->next;
		}
		else
		{
			pc->next = pb;
			pc = pb;
			pb = pb->next;
		}
	}
	//插入剩余段
	pc->next = pa?pa:pb;
	//释放Lb的头结点
	delete pb;
}

3. 顺序有序表的合并

void MergeList(List La,List Lb,List &Lc)
{
	InitList(Lc);
	i = j = 1;
	k = 0;
	La_len = ListLength(La);
	La_len = ListLength(La);
	while(i<=La_len)&&(j<=Lb_len)
	{   	
		GetElem(La,i,ai); 
		GetElem(Lb,j,bj);
		if (ai<=bj)
		{
			ListInsert(Lc,++k,ai);
			++i;
		}
		else
		{
            ListInsert(Lc,++k,bj);
            ++j;
        }
     }
     while (i<=La_len)
     {
     	GetElem(La,i++,ai);
     	ListInsert(Lc,++k,ai);
     }
     while (j<=Lb_len)
     {
     	GetElem(Lb,j++,bj);
     	ListInsert(Lc,++k,bj);
     } 
}

猜你喜欢

转载自blog.csdn.net/weixin_43790779/article/details/106398256