01 线性表

157 阅读3分钟

一、顺序表顺序存储结构

// 顺序表的存储结构  
typedef struct {
    ElemType *elem;		// 存储空间基地址 
    int length;			// 线性表的长度 
}SqList;

顺序表的初始化

typedef int Status;
#define MAXSIZE 10000
Status InitList(SqList &L) {		// 传引用(c++)
	// 构造空顺序表L
	L.elem = (int *)malloc(sizeof(int) * MAXSIZE);		// 分配一个MAXSIZE大小数组空间 
	if(!L.elem) exit(0);
	L.length = 0;
	return 1;
}

顺序表的取值

Status GetElem(SqList L, int i, ElemType &e) {
	if(i < 1 || L.length) return 0;		// i是否合理
	e = L.elem[i-1];
	return 1; 
}

顺序表的查找

int LocateElem(SqList L, ElemType e) {
	// 在顺序表L中查找值e的数据元素,返回序列号
	for(int i = 0; i < L.length; i++) {
		if(L.elem[i] == e) return i+1;
	} 
	return 0;	// 没找到 
}

顺序表的插入

Status ListInsert(SqList &L, int i, ElemType e) {
	//在顺序表L中第i个位置插入新的元素e,1 <= i <= L.length+1
	if(i < 1 || i > L.length+1) return 0;		// i不合理
	if(L.length == MAXSIZE) return 0;			// 当前储存空间满
	for(int j = L.length-1; j >= j - 1; j--) {
		L.elem[j+1] = L.elem[j];	// 插入元素之后全部元素往后移一格 
	} 
	L.elem[i-1] = e;				// 插入元素
	L.length++;
	return 1; 
} 

顺序表的删除

Status ListDelete(SqList &L, int i) {
	//在顺序表L中删除第i个元素,1 <= i <= L.length
	if(i < 1 || i > L.length) return 0;			// i不合理
	for(int j = i; j <= L.length-1; j++) {
		L.elem[j-1] = L.elem[j];	// 删除元素之后全部向前移一格 
	} 
	L.length--;
	return 1;
}

二、顺序表的链式存储结构

typedef int ElemType ;
typedef struct LNode {
	ElemType data;		// 数据域 
	struct LNode *next;	// 指针域 
}LNode, *LinkList;

单链表的初始化

typedef int Status;
#define MAXSIZE 1000
Status InitList(LinkList &L) {
	// 构造空链表L
	L = (LinkList) malloc (sizeof(LNode) * MAXSIZE); 
	L->next = NULL;		// 头结点的指针域置空
	return 1; 
}

单链表的取值

Status GetElem(LinkList L, int i, ElemType &e) {
	// 在带头结点的单链表L中根据序号i获取元素的值,用e返回第i个元素
	LinkList p = L->next;
	int j = 1;
	
	while(p && j < i) {		// 将指针移到i位置 
		p = p->next;
		j++;
	} 
	if(!p || j > i) return 0;
	e = p->data;
	return 1; 
}

单链表的查找

LNode *LocateElem(LinkList L, ElemType e) {
	// 在带头结点的单链表L中查找值e的元素
	LinkList p = L->next;
	
	while(p && p->data != e) {
		p = p->next;
	} 
	return p;		// 找到则返回e节点的地址, 找不到则返回NULL 
}

单链表的插入

Status ListInsert(LinkList &L, int i, ElemType e) {
	// 在带头结点的单链表L中第i个位置插入值为e的新节点
	LinkList p = L;
	int j = 0;
	
	while(p && j < i - 1) {
		p = p->next;
		j++;
	}
	if(!p || j > i - 1) return 0;
	LinkList s = (LinkList) malloc (sizeof(LNode));
	s->data = e;
	s->next = p->next;
	p->next = s;
	return 1;
}

单链表的删除

Status ListDelete(LinkList &L, int i) {
	// 在带头结点的单链表L中,删除第i个元素
	LinkList p = L;
	int j = 0;
	
	while(p->next &&  j < i - 1) {
		p = p->next;
		j++;
	}
	if(!(p->next) || (j > i - 1)) {
		return 0;
	}
	LinkList q = p->next;	// 保留要删除的元素
	p->next = q->next;
	free(q);
	return 1; 
}

头插法创建单链表

void CreateList_H(LinkList &L, int n) {
	// 头插法创建单链表
	L = (LinkList) malloc (sizeof(LNode));
	L->next = NULL;
	for(int i = 0; i < n; i++) {
		LinkList p = (LinkList) malloc (sizeof(LNode));
		cin >> p->data;
		p->next = L->next;
		L->next = p;
	}
}

尾插法创建单链表

void CreateList_R(LinkList &L, int n) {
	// 尾插法创建单链表
	L = (LinkList) malloc (sizeof(LNode));
	L->next = NULL;
	LinkList r = L;		// 尾指针 
	for(int i = 0; i < n; i++) {
		LinkList p = (LinkList) malloc (sizeof(LNode));
		cin >> p->data;
		p->next = NULL;
		r->next = p; 
		r = p;			// 尾指针移动到末尾 
	} 
}

三、双向链表

// 双向链表
typedef int ElemType;
typedef struct DuLNode {
	ElemType data;			// 数据域 
	struct DuLNode *prior;	// 指向直接前驱 
	struct DuLNode *next;	// 指向直接后继 
}DuLNode, *DuLinkList; 

双向链表的插入

Status ListInsert_DuL(DuLinkList &L, int i, ElemType e) {
	// 在带头结点的双向链表L中第i个位置之后插入元素e
	DuLinkList p;	// 指到第i个元素位置 
	if(!(p = GetElem_DuL(L, i))) return 0;	// 在L中确定第i个元素的位置指针是否存在
	DuLinkList s = (DuLinkList) malloc (sizeof(DuLNode));
	s->data = e;
	
	s->prior = p;			// 先将新结点指向两端 
	s->next = p->next;
	
	p->next->prior = s;		
	p->next = s; 			// 最后才能将p->next指向s,因为二三步骤都要p->next
	
	return 1; 
}

双向链表的删除

Status ListDelete_DuL(DuLinkList &L, int i) {
	// 删除带头结点的双向链表L中的第i个元素
	DuLinkList p;
	if(!(p = GetElem(L, i))) return 0;
	
	p->prior->next = p->next;	// p前面的元素直接指向下一个元素 
	p->next->prior = p->prior;	// p后面元素直接前驱改成p前面结点
	
	free(p);
	return 1; 
}