有关链表的学习


前言

本文是学习线性表、链表的记录。包括各种链表的基本操作,遇到题目会继续更新。大部分代码是C++,偶尔C。


一、顺序表的定义与操作

顺序存储的优点:
(1)结点等长可实现随机存取
(2)存储密度高,节省空间
(3)符合物理存储次序
顺序存储的缺点:
(1)插入删除时要移动大量结点
(2)必须静态分配连续空间

1.定义与初始化

typedef int Position;
typedef struct LNode *List;
struct LNode{
	ElementType Data[MAXSIZE];
	Position Last;
};
/*初始化*/
List MakeEmpty(){
	List L;
	L = (List)malloc(sizeof(struct LNode));
	L->Last = -1; 
	return L;
} 

2.查找

/*查找*/
#define ERROR -1
Position Find(List L,ElementType x){
	Position i = 0;
	while(i <= L->list &&L->Data[i] != x) i++;
	if(i > L->Last)  return ERROR;
	else return i;
}

3.插入

/*插入*/
bool Insert(List L,ElementType x,Position P){
	Position i;
	if(L->Last == MAXSIZE-1){
		printf("表满");
		return false; 
	}
	if(P < 0 || P > L->Last+1){
	    printf("位置不合法");
	    return false;
	}
	for(i = L->Last;i >= P;i--){
		/*位置P后元素顺序后移*/ 
		L->Data[i+1] = L->Data[i];
	}
	L->Last[i] = x;
	L->Last++;//指向最后元素 
	return true; 
} 

3.删除

/*删除*/
bool Delete(List L,Position P){
	Position i;
	if(P < 0||P > L->Last){
		printf("位置%d不存在元素",P);
		return false;
	}
	for(i = P+1;i <= L->Last:i++){
		/*如果从P开始,最后的i+1会出链表尾*/ 
		L->Data[i-1] = L->Data[i];
	}
	L->Last--;
	return true;
} 

二、单链表的定义与操作

链式存储的优点:
(1)插入删除比较灵活,不需要大量移动结点
(2)动态分配空间比较灵活,不需要提前申请最大连续空间
链式存储的缺点:
(1)增加指针空间开销
(2)检索必须沿链进行,不能随机存取

1.定义

typedef struct LNode *pLink;
struct LNode{
	ElementType Data;
	Link Next; 
};
typedef pLink Position;
typedef pLink List;

1.整表创建

(1)头插法

/*单链表的创建(头插法)*/
void CreateListHead(List L,int n){
	Position pre;
	int i;
	srand(time(0));//生成随机数做data
	L = (List)malloc(sizeof(struct LNode));
	L->next = NULL;
	for(i = 0;i < n;++i){
		pre =(Position)malloc(sizeof(struct LNode));
		pre->Data = rand()%100+1;//随机生成100以内的数字
		pre->Next = L->Next;
		L->Next = pre;   //插入到表头 
	} 
}

(2)尾插法

/*单链表的创建(尾插法)*/
bool CreateListTail(List L,int n){ 
    Position tmp,tail;
    int i;
    srand(time(0));
    L = (List)malloc(sizeof(struct LNode));
    tail = L;
    for(i = 0;i < n;++i){
    	tmp = (Position)malloc(sizeof(struct LNode));
		tmp->Data = rand()%100+1;
    	tail->Next = tmp;    	
    	tail = tmp;
	}
    tail->Next = NULL; 
    return true;
}

2.查找

/*查找*/
#define ERROR NULL
Position Find(List L,ElementType x){
	Position p = L; //p指向第一结点
	while(p && p->Data != x)
	   p = p->Next;
	return p;
	/*如果到最后退出循环,下一个也是NULL,同ERROR*/ 
} 

3.插入

/*带头结点的插入*/
bool Insert(List L,ElementType x,Position P){
	Postion tmp,pre;
	for(pre = L;pre && pre->next != P;pre = pre->next)
	if(pre == NULL){
	/*P不在中*/
	    cout<<"插入位置参数错误"<<endl; 
	    return false;
	}
	else{
    /*找到P的前一个结点*/
	    tmp = (Position)malloc(sizeof(struct Lnode));
		tmp->data = x;
		tmp->Next = P;
		pre->Next = tmp;
		return true; 
	}
} 

4.删除

/*带头结点的删除*/
bool Delete(List L,Position P){
	Position pre;
	for(pre = L;pre && pre->Next != P;pre = pre->Next)
	if(pre == NULL || P ==NULL)
	    cout<<"删除位置参数错误"<<endl;
	    return false;
	else{
		pre->Next = P->Next;
		free(P);
		return true;
	} 
} 

5.整表清空

/*单链表的清空*/
bool ClearList(List L){
	Position pre,tmp;
	pre = L->Next;
	while(pre)
	{
		tmp = pre->Next;
		free(pre);
		pre = tmp; 
	}
	L->Next = NULL;
	return true;	
} 

最后

掌握了基础操作后,还需要多练习加深理解。
如以上有问题,请不吝赐教。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值