数据结构(一) 数组和链表

一、数组

1.实现一个支持动态扩容的数组

//定义数组类型 
#define MAX_DIM 8  //最大维数 
typedef struct
{
	datatype *base;  //数组基址 
	int dim;  //数组维数 
	int *bound;  //辅助向量bound 
	int *const;  //辅助向量const 
}array;

//数组生成算法
int Setarray(array*A, int n, int dim[])  //生成n维数组A的算法,其中dim[]存放各维数长度 
{
	int i, etotal;
	if(n<1 || n>MAX_DIM) return(0);  //非法维数 
	(*A).dim = n;  //存入维数
	(*A).bound = (int*)malloc(n*sizeof(int));  //生成bound空间
	if(!(*A).bound) return(0);  //内存分配失败
	etotal = 1;
	for(i=0; i<n; i++)
	{
		if(dim[i]<0) return (0);  //非法维长度 
		(*A).bound[i] = dim[i];  //各维下标 
		etotal *= dim[i];  //统计元素个数 
	 }
	 (*A).base = (datatype*)malloc(etotal*sizeof(datatype));  //生成数组空间 
	 if(!(*A).base) return(0);
	 (*A).const = (int*)malloc(n*sizeof(int));  //生成const空间
	 if(!(*A).const) return(0);
	 (*A).const[n-1] = 1;
	 for(i=n-2; i>=0; i--)
	 {
	 	(*A).const[i] = (*A).bound[i+1]*(*A).const[i+1];  //给const赋值
	return (1); 
	 }
 } 

or

template <typename T> void Vector<T>::expand(){  //向量空间不足时扩容 
	if(_size_ < capacity) return;  //尚未满员时不必扩充
	if(_capacity < DEFAULT_CAPACITY) _capacity = DEFAULT_CAPACITY;  //不低于最小容量
	T* oldElem = _elem; _elme = new T[_capacity <<= 1];  //容量加倍
	for(int i = 0; i < _size; i++)
		_elem[i] = oldElem[i];  //复制原向量内容(T为基本类型,或已重载赋值操作符'm')
	delete [] oldElem;  //释放空间 
}

2.实现一个大小固定的有序数组,支持动态增删改操作

3.实现两个有序数组合并为一个有序数组

4.学习哈希表思想,并完成leetcode上的两数之和(1)及Happy Number(202)!(要求全部用哈希思想实现!)(选做)

二、链表

1.实现单链表、循环链表、双向链表,支持增删操作

//节点类型描述
typedef int datatype;  //设置当前数据元素为整型 
typedef struct node  //节点类型 
{
	datatype data;  //节点的数据域 
	struct node *next;  //节点的后继指针域 
}linknode, *link;  //linknode为节点说明符,link为节点指针说明符

1)单链表

//创建单链表
link Createlist()  //创建单链表的算法 
{
	link H;
	H = (link)malloc(sizeof(linknode));  //建立头节点 
	H->nest = NULL;  //将尾节点(这里就是头节点)的指针域置空 
	return (H);  //返回已创建的头节点 
}
//输入数据创建链表
link Createlist()  //创建单链表的算法
{
	link a;
	link H, P, r;  //H, P, r分别为表头,新节点和表尾节点指针 
	H = (link)mallloc(sizeof(linknode));  //建立头结点
	r = H;
	scanf("%d", &a);  //输入一个数据
	while(a != -1)
	{
		P = (link)malloc(sizeof(linknode));  //申请新节点
		P->data = a;  //存入数据 
		r->next = P;  //新节点链入表尾 
		r = P;
		scanf("%d", &a);  //输入下一数据 
	}
	r->next = NULL;  //将尾节点的指针域置空 
	return (H);  //返回已创建的头节点 
}
//查找
//1.按序号查找
Link GetElem(link H, int i)  //查找单链表H中第i节点的指针的算法
{
	int j = -1;
	link P = H;  //令指针P指向头节点 
	if(i < 0) return (NULL);  //参数错,返回NULL 
	while(P->next && j<i)  //若当前节点存在且不为第i个节点时 
	{
		P = P->next;  //取P节点的后继 
		j++;
	}
	if(i==j) return(P);  //返回第i节点的指针 
	else return(NULL);  //查找失败,即i>表长 
 } 
//2.按值查找(定位)
link LocateElem(link H, datatype e)  //在单链表中查找元素值为x的节点的算法
{
	link P = H->next;  //令指针P指向节点a0
	while(P && P->data!=e)  //e为待查找值
	P = P->next;  //继续向后查找
	return (P);  //若查找成功(即某个P->data=e)则返回指针P;否则P必为空,返回NULL 
}
//前插
void ListInsert(link H, int i, datatype e)  //在单链表h中将节点x插入到节点ai之前的算法
{
	link p, q;
	if(i==0) p=H; else p = GetElem(H, i-1);  //取节点ai-1的指针 
	
	if(p=NULL) ERROR(i);  //参数i出错 
	else
	{
		q = (link)malloc(sizeof(linknode));  //申请插入节点 
		q->data = x;  //存入数据 
		q->next = p->next;  //插入新节点 
		p->next = q;
	}
} 
//删除
void LiseDel(link H, int i)  //删除单链表H中节点ai的算法
{
	link p, q;
	if(i==0) p=H; else p = GetElem(H, i-1);  //取节点ai-1的指针  
	if(p && p->next)  //若p及p->next所在的节点存在 
	{
		q = p->next;
		p->next = q->next; //删除 
		free(q);  //释放被删除的节点 
	}
	else ERROR(i);  //参数i出错 
 } 

2)循环链表
将链表的头节点与尾节点连接起来即可

3)双向链表

//双向链表
typedef struct dnode  //双向链表节点
{
	datatype data;
	struct dnode *prior, *next;  //prior指向本节点的直接前驱 
}dlinknode, *dlink
//前插
void Dinsert(dlink L, int i, datatype x)  //将节点x插入双向链表L中都第i节点之前的算法
{
	dlink p, q;
	p = Getlist(L, i)  //取节点ai的指针, Getlist(L, i)为双向链表查找算法
	if(p == NULL) Error(i);
	else
	{
		q = (dlink)malloc(sizeof(dlinknode));  //申请q节点 
		q->data = x;  //存入数据 
		q->prior = p->prior;  //修改指针,将q节点插入 
		q->next = p;
		(p->prior) -> next = q;
		p->prior = q;
	}
}
//删除
void Ddelete(dlink L, int i)  //删除双向链表中第i节点的算法 
{
	dlink p;
	p = Getlink(L, i);  //取节点ai的指针
	if(p = NULL) Error(i);  //参数i出错 
	else{
		(p->prior) -> next = p->next;
		(p->next) -> prior = p->prior;
		free(p);
	} 
}

2.实现单链表反转

//实现单链表反转
void L1n-Ln1(link H)  //求单链表H的倒置算法
{
	link p, q;
	p = H->next;  //令指针p指向节点a0 
	H->next = NULL;  //先将原链表置零 
	while(p)
	{
		q = p;
		p = p->next;
		q->next = H->next;  //将节点ai插入到头节点之后 
		H->next = q;
	}
}

3.实现两个有序的链表合并为一个有序链表

//实现两个有序的链表合并为一个有序链表
void Merge(link A, link B)   //将两个递增表合并成一个递增有序表的算法 
{
	link r, p, q;
	p = A->next;
	q = B->next;
	free(B);
	r = A;  //指针r为结果表的表尾指针 
	while(p && q)
	{
		if(p->data <= q->data)
		{
			r->next = p; r = p;  //p节点进结果表 
			p = p->next;
		}
		else
		{
			r->next = q; r = q;  //q节点进结果表 
			q = q->next;
		}
	}
	if(p == NULL) p = q;  //收尾处理 
	r->next = p;
}

4.实现求链表的中间结点

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值