读书笔记 ——《大话数据结构》—— 线性表

《大话数据结构》—— 线性表

1.时间复杂度效率

O(1) > O(logn) > O(n) > O(nlogn) > O(n^2) > O(n^3) > O(2^n) > O(n!) > O(n^n) 

2.线性表

2.1线性表——顺序存储

// 线性表----顺序存储 
#include <stdio.h>
#include <stdlib.h>

#define MAXSIZE 1024

typedef int ElementType;
typedef struct
{
	ElementType data[MAXSIZE];			// 数组存储数据元素 
	int length;					// 当前线性表长度 
}SqList;

SqList * InitList(SqList * L);				// 初始化线性表(空表) 
int GetElem(SqList * L, int i, ElementType * e); 	// 获取线性表L第i个元素给e 
int ListInsert(SqList * L, int i, ElementType e);	// 插入元素 
int ListDelete(SqList * L, int i, ElementType * e);	// 删除元素
int PrintList(SqList * L); 				// 遍历线性表 
int ClearList(SqList * L); 			        // 清空线性表 
int DestoryList(SqList * L);			        // 销毁线性表 

int main()
{	
	SqList * L = NULL;
	L = InitList(L);
	if (L!=NULL) {
		printf("初始化线性表(空表)成功\n");
	}
	ListInsert(L, 1, 999);
	ListInsert(L, 2, 888);
	ListInsert(L, 3, 777);
	PrintList(L);
	printf("\n清空线性表...\n");
	ClearList(L);
	PrintList(L);
}

// 初始化顺序表(空表)
SqList * InitList(SqList * L)
{
	L = (SqList *)malloc(sizeof(SqList));
	if (L!=NULL) {
		L->length = 0;
	}
	return L;
} 
// 获取线性表L第i个元素给e  
int GetElem(SqList * L, int i, ElementType *e)
{
	if (L->length == 0 || i<i || i>L->length) {
		return 0;
	}
	*e = L->data[i-1];
	return 1;
} 
// 插入元素 
int ListInsert(SqList * L, int i, ElementType e)
{
	if (L->length == MAXSIZE) {		// 判断线性表是否已满 
		return 0;
	}
	if (i<1 || i>L->length + 1) {
		return 0;
	}	
	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 1;
}
// 删除元素
int ListDelete(SqList * L, int i, ElementType *e)
{
	if (L->length == 0) {
		return 0;
	} 
	if (i<1 || i>L->length) {
		return 0;
	}
	*e = L->data[i-1];
	if (i<L->length) {
		for (int k = i; k<L->length;k++) {
			L->data[k-1] = L->data[k];
		}
	}
	L->length--;
	return 1;
} 
// 遍历线性表
int PrintList(SqList * L)
{
	if (L->length == 0) {
		printf("线性表为空!\n"); 
	}
	for (int i = 0; i< L->length; i++) {
		printf("a[%d]=%d\t", i, L->data[i]);
		if ((i + 1) % 5 == 0) {
			printf("\n");
		}
	}
	return 1;
} 
// 清空线性表
int ClearList(SqList * L)
{
	L->length = 0;
	return 1;	
}
// 销毁线性表
int DestoryList(SqList * L)
{
	free(L);
	return 1;	
} 

2.2线性表——链式存储结构

// 线性表----链式存储
#include <stdio.h>
#include <stdlib.h>

typedef int ElementType; 
typedef struct Node
{
	ElementType data;
	struct Node * next;
} Node;
typedef struct Node * LinkList;	
// LinkList = struct Node * 
// LinkList * L : 二级指针,L为struct Node ** 类型,只能存放struct Node *类型变量的地址 

void CreateListHead(LinkList * L, int n);			// 头插法建立单链表 
void CreateListTail(LinkList * L, int n);			// 尾插法建立单链表
int ListInsert(LinkList * L, int i, ElementType e);		// 插入元素 
int ListDelete(LinkList * L, int i, ElementType * e);	        // 删除元素 
int GetElem(LinkList L, int i, ElementType * e);		// 获取元素 
int PrintList(LinkList L);					// 遍历单链表
int ClearList(LinkList * L);					// 整表删除

int main()
{
	LinkList L; 			// = struct Node * L
	CreateListTail(&L, 10);		// &L:struct node * 类型的地址 
	PrintList(L);
	ListInsert(&L, 2, 666);
	PrintList(L);
	ClearList(&L);
	PrintList(L);
} 
// 头插法建立单链表 
void CreateListHead(LinkList * L, int n)
{
	LinkList p;
	*L = (LinkList)malloc(sizeof(Node));	
	(*L)->next = NULL;
	for (int i = 0; i<n; i++)
	{
		p = (LinkList)malloc(sizeof(Node));
		p->data = i;
		p->next = (*L)->next;
		(*L)->next = p;
	}
}
// 尾插法建立单链表
void CreateListTail(LinkList * L, int n)
{
	LinkList p, r;
	*L = (LinkList)malloc(sizeof(Node));
	r = *L;	                        // r指向尾部的结点 
	for (int i = 0; i<n; i++)
	{
		p = (LinkList)malloc(sizeof(Node));
		p->data = i;
		r->next = p;	        // 表尾结点指向新结点 
		r = p;			// 新节点为尾部结点r 
	}
	r->next = NULL;
}
// 插入元素 
int ListInsert(LinkList * L, int i, ElementType e)
{
	int j;
	LinkList p, s;			
	p = *L;		 
	j = 1;			
	while (p && j<i) {
		p = p->next;
		++j;
	}
	if (!p || j>i) {
		return 0;
	}
	s = (LinkList)malloc(sizeof(Node));
	s->data = e;
	s->next = p->next;
	p->next = s;
	return 1;
} 
// 删除元素 
int ListDelete(LinkList * L, int i, ElementType * e)
{
	int j;
	LinkList p, q;			
	p = *L;		 
	j = 1;			
	while (p->next && j<i) {
		p = p->next;
		++j;
	}
	if (!p || j>i) {
		return 0;
	}
	q = p->next;
	p->next = q->next;
	*e = q->data;
	free(q);
	return 1;	
} 
// 获取元素 
int GetElem(LinkList L, int i, ElementType * e)
{
	int j;
	LinkList p;		// 声明一指针p
	p = L->next;		// p指向L的第一个结点 
	j = 1;			// j为计数器 
	while (p && j<i) {
		p = p->next;
		++j;
	}
	if (!p || j>i) {
		return 0;
	}
	*e = p->data;
	return 1;
}
// 遍历单链表
int PrintList(LinkList L)
{
	LinkList p;
	p = L->next; 
	if (p == NULL) {
		printf("该链表为空!");
	}
	while (p !=NULL) {
		printf("%d ", p->data);
		p = p->next; 
	}
	printf("\n");
	return 1;
}
// 整表删除
int ClearList(LinkList * L)
{
	LinkList p, q;		
	p = (*L)->next;		// p指向第一个结点 
	while(p) {
		q = p->next;
		free(p);
		p = q;
	}
	(*L)->next = NULL;	// 头结点指针域为空 
	return 1;
} 

顺序存储和单链表对比

存储分配方式

  • 顺序存储采用一段连续的存储单元一次存储线性表的数据元素
  • 单链表采用链式存储结构,用一组任意的存储单元存放线性表的元素

时间性能

  • 查找:顺序存储结构O(1)、单链表O(n)
  • 插入和删除:顺序存储结构需要平均移动表长一半的元素,时间为O(n)、单链表在找出某位置指针后,插入和查询仅为O(1)

空间性能

  • 顺序存储结构需要预先分配空间、单链表不需要预先分配存储空间

2.3静态链表

..


猜你喜欢

转载自blog.csdn.net/qq_36045946/article/details/81050972