数据结构学习日记(四)

一,双链表

单链表只包含后继节点的指针,从一个节点出发只能找到后继的各个节点

双链表又添加一个指针域,指向前驱节点,表头节点的prior指向null,表尾节点的next指向null。

(1)双链表的初始化

(2)双链表的插入

(3)双链表的删除

(4)双链表的遍历

二,循环链表

(1)循环单链表,从一个节点出发可以找到其他任何一个节点

(2)循环双链表,表头节点的prior指向表尾节点,表尾节点的next指向头结点。

三,单链表的基本操作代码示意:1-12

#include <stdlib.h>
#include <stdio.h>
typedef struct LNode{
	int data;//每个节点存放一个int类型的数据元素 
	Struct Lnode *next;//指针指向下一个节点 	
}LNode,*LinkList;//将struct LNode重命名为LNode,并表示使用LinkList作为一个指针指向Struct lNODE. 
//1,初始化不带头节点 ,LNode *L等价与LinkList L,声明一个指向单链表的第一个节点的指针 
bool InitList1(LinkList &L){
	L=NULL;
	return true;
} 
//2,初始化带头节点
bool InitList2(LinkList &L){
	L=(LNode *)malloc(sizeof(LNode));
	L->next=NULL;
	return true;
}
//3, 带头节点的插入
bool InsertList1(LinkList &L,int i,int e){
	if(i<1){
		return false;
	}
	LNode *p;//定义一个指针p指向当前扫描到的节点
	int j=0;//记录p指向第几个节点
	p=L;//从头节点开始 ,l指向头结点
	while(p!=NULL&&j<i-1){
		p=p->next;
		j++;
	}
	LNode *s=(LNode*)malloc(sizeof(LNode));
	s->data=e;
	s->next=p->next;
	p->next=s;
	return true; 
}
//4,不带头结点的插入,需考虑第一个特殊节点 
bool InsertList1(LinkList &L,int i,int e){
	if(i<1){
		return false;
	}
	//插入第一个节点时候不同
	if(i==1){
		LNode *s=(LNode*)malloc(sizeof(LNode));
		s->data=e;
		s->next=L;//新节点指向l指向的节点也就是头结点 
		L=s;//l指向新节点
		return true; 
	} 
	LNode *p;//定义一个指针p指向当前扫描到的节点
	int j=0;//记录p指向第几个节点
	p=L;//从头节点开始 ,l指向头结点
	while(p!=NULL&&j<i-1){
		p=p->next;
		j++;
	}
	LNode *s=(LNode*)malloc(sizeof(LNode));
	s->data=e;
	s->next=p->next;
	p->next=s;
	return true; 
}
//5,不带头节点的插入之:前插,偷天换日,实际是与p节点交换了数据 
bool InsertList2(LinkList p,int e){
	if(p==NULL){
		return false;
	}
	LNode *s=(LNode *)malloc(sizeof(LNode));
	if(s==NULL){
		return false;
	}
	s->next=p->next;
	p->next=s;
	s->data=p->data;
	p->data=e;
	return true; 	
}
//6,不带头节点的插入之:后插
bool InsertList2(LinkList &p,int e){
	if(p==NULL){
		return false;
	}
	LNode *s=(LNode*)malloc(sizeof(LNode));
	if(s==NULL){
		return false;
	}
	s->data=e;
	s->next=p->next;
	p->next=s;
	return true;
}
//7,带头节点的删除,循换找到位序-1的节点,定义q指向要被删除的节点,断开该节点,最后释放q节点存储空间 
bool DeleteList(LinkList &L,int i,int &e){//e为引用类型,要带回数据 
	if(i<1){
		return false;
	}
	LNode *p; //定义一个指针指向当前扫描到的节点
	int j=0;//记录p指向第几个节点
	while(p!=NULL && j<i-1){
		p=p->next;
		j++;
	} 
	if(p==NULL){
		return false;
	}
	if(p->next==NULL){
		return false;
	}
	LNode *q=p->next;//q指向被删除节点 
	e=q->data;//e返回删除元素 
	p->next=q->next;//断开 
	free(q);
	return true;
} 
//8,带头节点的指定节点删除
bool DeleteList(LinkList &p){
	if(p==null){
		return false;
	}
	LNode *q=p->next;
	p->data=p->next->data;
	p->next=q->next;
	free(q);
	return true;	
}
//9,带头节点按位查找
LNode *LocateElem(LinkList &L,int i){
	if(i<1){
		return NULL;
	}
	LNode *p;//指针p指向当前扫描的节点
	p=L;//从头结点开始
	int j=0;
	while(p!=NULL&&j<i){
		p=p->next;
		j++;
	}
	return p;
	
} 
//10,带头节点的按值查找 
LNode *Getelem(LinkList &L,int e){
	LNode *p=L;
	while(p!=NULL&&p->data!=e){
		p=p->next; 
	}
	return p;
}
//11,求表的长度
int Length(LinkList &L){
	LNode *p=L;
	int j=0;
	while(p->next!=NULL){
		p=p->next;
		j++;
	}
	return j;
} 
//12,建立单链表,尾插法
LinkList List_Tailnsert(LinkList &L){
	L=(LinkList)malloc(sizaof(LNode));
	LNode *s,*r=L;
	int x;
	scanf("%d",&x);
	while(x!=9999){
		s=(LNode *)malloc(sizeof(LNode));
		s->data=x;
		r->next=s;
		r=s;
	}
	r->next=NULL;//r为尾指针,此时为空 
	return L;
}
//12,头插法
LinkList List_Headnsert(LinkList &L){
    L=(LinkList)malloc(sizaof(LNode));
    L->next=NULL;
	LNode *s;
	int x;
	scanf("%d",&x);
	while(x!=9999){
		s=(LNode *)malloc(sizeof(LNode));
		s->data=x;
		s->next=L->next;
		L->next=s;
		scanf("%d",&x);
	}
	return L;
	 
} 

四,每日一题:剑指 Offer 24. 反转链表

(1)双指针

class Solution {
    public ListNode reverseList(ListNode head) {
        ListNode cur=head,per=null;//定义cur指向头节点,per指向null
        while(cur!=null){
            ListNode temp=cur.next;//定义temp
            cur.next=per;//修改指向
            per=cur;//per
            cur=temp;            
        }
        return per;
    }
}

五,理论知识:

(1)java向上转型,比如char自动转为int类型

(2)数组引用类型的变量的默认值为 null

(3)执行顺序优先级:静态域,main(),构造代码块,构造方法。

       静态块:用static申明,JVM加载类时执行,仅执行一次
       构造块:类中直接用{}定义,每一次创建对象时执行
  (4)线程安全问题:Vector相当于一个线程安全的List

                             HashMap是非线程安全的,其对应的线程安全类是HashTable

                              Arraylist是非线程安全的,其对应的线程安全类是Vector

                            StringBuffer是线程安全的,相当于一个线程安全的StringBuilder

                              Properties实现了Map接口,是线程安全的

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值