二、链表
一、链表的概念与特点
1.存储特点:结点在存储器中的位置是任意的,即逻辑上
相邻的数据元素在物理上不一定相邻。
2.链表中的结点由数据域(存储的元素)和指针域(相邻结点的地址)构成。
3.链表分为单链表、双链表、循环链表
·单链表:结点的指针域中只存储下一个结点的地址值(即链表只能单向遍历)。
·双链表:结点的指针域中存储相邻两个结点的地址值(可双向遍历)
·循环链表:首尾相接的链表
4.头指针是指向第一个结点的指针,首元结点是链表中第一个存储数据的结点。
5.链表中可以存在头结点,头结点中可以为空,也可以存储链表的附加信息,其地址域中保存首元结点的地址值。
6.单链表由表头唯一确定,因此可以头指针的名字命名单链表。
7.插入元素可以在链表的头部插入,即头插法,在尾部插入为尾插法。
二、连表的时间复杂度
1.查找:由于链表只能顺序读取,因此查找元素的时间复杂度为O(n)
2.插入与删除:
·若在头尾部添加或删除元素,由于不需要移动元素,因此时间复杂度一般为O(1)
·若在链表中间更改元素,时间复杂度为O(n)
三、单链表的java实现
class LinkedList<T>{
private class Obj{
private T t;
private Obj next = null;
Obj(T t){
this.t = t;
}
}
private class struct{
Obj obj;
int i;
public struct(Obj obj, int i){
this.obj=obj;
this.i=i;
}
}
private Obj first;
private Obj last;
private int length;
public void add(T next){
if (length == 0){
first = new Obj(next);
last = first;
length++;
return;
}
last.next = new Obj(next);
last = last.next;
length++;
}
private struct get(int i){
if (i <1||i>length){
return new struct(null,0);
}
int j = 1;
Obj temp = first;
while (j<i){
temp = temp.next;
j++;
}
return new struct(temp,i);
}
private struct get(T t){
int j = 1;
Obj temp = first;
while (j<length){
if (temp.t.equals(t)){
return new struct(temp,j);
}
temp=temp.next;
j++;
}
return new struct(null,0);
}
public boolean insert(int i, T t){
if (i < 1 || (i > length && length > 0)){
return false;
}
if (i == length){
add(t);
return true;
}
Obj temp = new Obj(t);
if (i == 1){
if (length==0){
length++;
first=temp;
last=temp;
return true;
}
temp.next = first;
first = temp;
length++;
return true;
}
length++;
Obj previous = get(i-1).obj;
temp.next = get(i).obj;
previous.next = temp;
return true;
}
public T getLast(){
if (length==0){
return null;
}
return last.t;
}
public T getFirst(){
if (length == 0){
return null;
}
return first.t;
}
public T delete(int i){
if (i < 1 || i > length){
return null;
}
int j = 1;
Obj result = get(i).obj;
if (i==1){
first=first.next;
length--;
return result.t;
}
Obj previous = get(i-1).obj;
previous.next=result.next;
if (i == length){
last = previous;
}
length--;
return result.t;
}
public T delete(T t){
return delete(find(t));
}
public T replace(T t, int i){
Obj result = get(i).obj;
if (result == null){
return null;
}
T temp = result.t;
result.t = t;
return temp;
}
public T find(int i){
Obj result = get(i).obj;
// System.out.println(result.t);
return result == null ? null : result.t;
}
public int find(T t){
return get(t).i;
}
public boolean replace(T target, T newOne){
Obj obj = get(target).obj;
if (obj == null){
return false;
}
obj.t=newOne;
return true;
}
public T replace(T target, T newOne, Comparator<T> cmp){
Obj temp = first;
int i = 1;
while (i <= length){
if (cmp.compare(temp.t, target) == 0){
T result = temp.t;
temp.t = newOne;
return result;
}
i++;
temp = temp.next;
}
return null;
}
public int find(T t, Comparator<T> cmp){
Obj temp = first;
int i = 1;
while (i <= length){
if (cmp.compare(temp.t, t) == 0){
return i;
}
i++;
temp = temp.next;
}
return 0;
}
public int getLength(){
return length;
}
public String toString(){
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("[");
Obj temp = first;
for (int i = 1; i < length; i++) {
stringBuilder.append(temp.t+",");
temp = temp.next;
}
stringBuilder.append(temp.t+"]");
return stringBuilder.toString();
}
//链表反转
public void reverse(){
if (length==0) {
return;
}
Obj here = first;
Obj next = here.next;
Obj previous = null;
for (int i = 0; i < length-1; i++) {
here.next = previous;
previous = here;
here = next;
next=next.next;
}
here.next = previous;
previous = here;
here = next;
Obj temp = first;
first=last;
last=temp;
}
public void clear(){
length=0;
last=first=null;
}
}
四、双向链表的java实现
class LinkedListTwo<T>{
private class Obj{
private T t;
private Obj previous;
private Obj next = null;
Obj(T t,Obj previous){
this.t = t;
}
}
private class struct{
Obj obj;
int i;
public struct(Obj obj, int i) {
this.obj = obj;
this.i = i;
}
}
private Obj first;
private Obj last;
private int length;
public void add(T next){
if (length == 0){
first = new Obj(next,null);
last = first;
length++;
return;
}
last.next = new Obj(next,last);
last = last.next;
length++;
}
private struct get(int i){
if (i <1||i>length){
return new struct(null,0);
}
int j = 1;
Obj temp = first;
while (j<i){
temp = temp.next;
j++;
}
return new struct(temp,i);
}
private struct get(T t){
int j = 1;
Obj temp = first;
while (j<length){
if (temp.t.equals(t)){
return new struct(temp,j);
}
temp=temp.next;
j++;
}
return new struct(null,0);
}
public boolean insert(int i, T t){
if (i < 1 || i > length){
return false;
}
if (i == length){
add(t);
return true;
}
Obj temp = new Obj(t,null);
if (i == 1){
length++;
temp.next = first;
first.previous = temp;
first = temp;
return true;
}
length++;
Obj previous = get(i-1).obj;
Obj target = new Obj(t,previous);
target.next = previous.next;
previous.next = target;
return true;
}
public T getLast(){
if (length==0){
return null;
}
return last.t;
}
public T getFirst(){
if (length == 0){
return null;
}
return first.t;
}
public T delete(int i){
if (i < 1 || i > length){
return null;
}
int j = 1;
Obj result = get(i).obj;
if(i==1){
first = first.next;
first.previous = null;
lengh--;
return result.t;
}
Obj previous = result.previous;
previous.next=result.next;
result.next.previous=previous;
if (i == length){
last = previous;
}
length--;
return result.t;
}
public T delete(T t){
return delete(find(t));
}
public T replace(T t, int i){
Obj result = get(i).obj;
if (result == null){
return null;
}
T temp = result.t;
result.t = t;
return temp;
}
public T find(int i){
Obj result = get(i).obj;
// System.out.println(result.t);
return result == null ? null : result.t;
}
public int find(T t){
return get(t).i;
}
public boolean replace(T target, T newOne){
int i = 1;
Obj result = get(target).obj;
if (result == null){
return false;
}
result.t = newOne;
return true;
}
public T replace(T target, T newOne, Comparator<T> cmp){
Obj temp = first;
int i = 1;
while (i <= length){
if (cmp.compare(temp.t, target) == 0){
T result = temp.t;
temp.t = newOne;
return result;
}
i++;
temp = temp.next;
}
return null;
}
public int find(T t, Comparator<T> cmp){
Obj temp = first;
int i = 1;
while (i <= length){
if (cmp.compare(temp.t, t) == 0){
return i;
}
i++;
temp = temp.next;
}
return 0;
}
public int getLength(){
return length;
}
public String toString(){
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("[");
Obj temp = first;
for (int i = 1; i < length; i++) {
stringBuilder.append(temp.t+",");
temp = temp.next;
}
stringBuilder.append(temp.t+"]");
return stringBuilder.toString();
}
}
五、循环链表的实现
class LinkedListThree<T>{
private class Obj{
private T t;
private Obj previous;
private Obj next = null;
Obj(T t,Obj previous){
this.t = t;
}
}
private class struct{
Obj obj;
int i;
public struct(Obj obj, int i) {
this.obj = obj;
this.i = i;
}
}
private Obj first;
private Obj last;
private int length;
public void add(T next){
if (length == 0){
first = new Obj(next,null);
last = first;
length++;
return;
}
last.next = new Obj(next,last);
last = last.next;
first.previous=last;
last.next=first;
length++;
}
private struct get(int i){
if (i <1||i>length){
return new struct(null,0);
}
int j = 1;
Obj temp = first;
while (j<i){
temp = temp.next;
j++;
}
return new struct(temp,i);
}
private struct get(T t){
int j = 1;
Obj temp = first;
while (j<length){
if (temp.t.equals(t)){
return new struct(temp,j);
}
temp=temp.next;
j++;
}
return new struct(null,0);
}
public boolean insert(int i, T t){
if (i < 1 || i > length){
return false;
}
if (i == length){
add(t);
return true;
}
Obj temp = new Obj(t,null);
if (i == 1){
length++;
temp.next = first;
first.previous = temp;
first = temp;
first.previous=last;
last.next=first;
return true;
}
length++;
Obj previous = get(i-1).obj;
Obj target = new Obj(t,previous);
target.next = previous.next;
previous.next = target;
return true;
}
public T getLast(){
if (length==0){
return null;
}
return last.t;
}
public T getFirst(){
if (length == 0){
return null;
}
return first.t;
}
public T delete(int i){
if (i < 1 || i > length){
return null;
}
Obj result = get(i).obj;
if (i==1){
first = first.next;
first.previous = last;
last.next=first;
length--;
return result.t;
}
Obj previous = result.previous;
previous.next=result.next;
result.next.previous=previous;
if (i == length){
last = previous;
previous.next=first;
}
if (i==1){
first=first.next;
first.previous=last;
last.next=first;
}
length--;
return result.t;
}
public T delete(T t){
return delete(find(t));
}
public T replace(T t, int i){
Obj result = get(i).obj;
if (result == null){
return null;
}
T temp = result.t;
result.t = t;
return temp;
}
public T find(int i){
Obj result = get(i).obj;
// System.out.println(result.t);
return result == null ? null : result.t;
}
public int find(T t){
return get(t).i;
}
public boolean replace(T target, T newOne){
int i = 1;
Obj result = get(target).obj;
if (result == null){
return false;
}
result.t = newOne;
return true;
}
public T replace(T target, T newOne, Comparator<T> cmp){
Obj temp = first;
int i = 1;
while (i <= length){
if (cmp.compare(temp.t, target) == 0){
T result = temp.t;
temp.t = newOne;
return result;
}
i++;
temp = temp.next;
}
return null;
}
public int find(T t, Comparator<T> cmp){
Obj temp = first;
int i = 1;
while (i <= length){
if (cmp.compare(temp.t, t) == 0){
return i;
}
i++;
temp = temp.next;
}
return 0;
}
public int getLength(){
return length;
}
public String toString(){
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("[");
Obj temp = first;
for (int i = 1; i < length; i++) {
stringBuilder.append(temp.t+",");
temp = temp.next;
}
stringBuilder.append(temp.t+"]");
return stringBuilder.toString();
}
}