第一次写博客,有错误欢迎指正。
需要从java改学c++,完全不会。
ps:代码的效率不高,只保证是能通过的。
链表
链表是线性表的一种
每个节点有一个前驱节点(头结点除外)和一个后继节点(最后一个节点除外);
链表不能随机访问;
链表的每个节点都是一个指针,会指向下一个元素;
单链表的设计
节点仅有值(val)和下一个节点(next)两个属性;
链表仅设有头结点(head)和大小(size)两个属性;
分析:
-
插入:
- 头:O(1);
- 尾:O(1);
- 任意位置:O(n);//对链表本身的改动较小,主要是找到插入点。
-
删除:
- 头:O(1);
- 尾:O(1);
- 任意位置:O(n);
-
查找:
- 根据index:O(n)
- 根据val:O(n); //没写代码
-
c++与java的语法区别:
- C++空值不能用null,要大写NULL;
- C++可以定义结构体,不需要用类定义,结构体定义完之后要加上分号;
- 因为结构体中next是指针,取值时要与“->";
- 要注意空指针异常。
-
问题:
- 为什么java中链表的节点直接定义为对象,而c++要把链表中的节点定义为指针?【c++中好像new的对象就需要用指针。。。指针是个神奇的东西,完全搞不懂。。。】
- 运行时间好长,求改进的方案。
-
改进
- 减少if-else语句。
- 加尾部节点
class MyLinkedList {
private:
struct MyListNode{
int val;
MyListNode *next;
MyListNode(int x):val(x), next(NULL) {}
};
MyListNode *head;
int size;
public:
/** Initialize your data structure here. */
MyLinkedList() {
head=NULL;
size=0;
}
/** Get the value of the index-th node in the linked list. If the index is invalid, return -1. */
int get(int index) {
if(size==0) return -1;
if(index<0||index>=size){
return -1;
}
MyListNode *temp=head;
for(int i=0;i<index;i++){
temp=temp->next;
}
return temp->val;
}
/** Add a node of value val before the first element of the linked list. After the insertion, the new node will be the first node of the linked list. */
void addAtHead(int val) {
MyListNode *temp=new MyListNode(val);
temp->next=head;
head=temp;
size++;
return ;
}
/** Append a node of value val to the last element of the linked list. */
void addAtTail(int val) {
if(head==NULL) {
addAtHead(val);
}
MyListNode *temp=head;
while(temp->next!=NULL){
temp=temp->next;
}
temp->next=new MyListNode(val);
size++;
return ;
}
/** Add a node of value val before the index-th node in the linked list. If index equals to the length of linked list, the node will be appended to the end of linked list. If index is greater than the length, the node will not be inserted. */
void addAtIndex(int index, int val) {
if(index<=0) addAtHead(val);//不等于时会报错。
else if(index==size) addAtTail(val);
else if(index>size) return;
else{
MyListNode *temp=head;
for(int i=0;i<index-1;i++){
temp=temp->next;
}
MyListNode *newNode=new MyListNode(val);
newNode->next=temp->next;
temp->next=newNode;
size++;
}
}
/** Delete the index-th node in the linked list, if the index is valid. */
void deleteAtIndex(int index) {
if(index<0||index>=size) return;
if(index==0) {
head=head->next;
size--;
return;
}
MyListNode *temp=head;
for(int i=0;i<index-1;i++){
temp=temp->next;
}
temp->next=temp->next->next;
size--;
}
};
/**
* Your MyLinkedList object will be instantiated and called as such:
* MyLinkedList* obj = new MyLinkedList();
* int param_1 = obj->get(index);
* obj->addAtHead(val);
* obj->addAtTail(val);
* obj->addAtIndex(index,val);
* obj->deleteAtIndex(index);
*/
双向链表的设计
节点的属性为值(val),前驱节点(prev)和后继节点(next)
链表的属性有头结点(head),尾结点(tail)以及长度(size)
注意:
- 插入和删除都要修改相邻节点的prev或next
- head的prev为NULL
- tail的next为NULL
class MyLinkedList {
private:
struct DoublyListNode {
int val;
DoublyListNode *next, *prev;
DoublyListNode(int x) : val(x), next(NULL), prev(NULL) {}
};
DoublyListNode *head,*tail;
int size;
public:
/** Initialize your data structure here. */
MyLinkedList() {
head=NULL;
tail=NULL;
size=0;
}
/** Get the value of the index-th node in the linked list. If the index is invalid, return -1. */
int get(int index) {
if(index<0||index>=size) return-1;
DoublyListNode *temp=head;
for(int i=0;i<index;i++){
temp=temp->next;
}
return temp->val;
}
/** Add a node of value val before the first element of the linked list. After the insertion, the new node will be the first node of the linked list. */
void addAtHead(int val) {
DoublyListNode *temp=new DoublyListNode(val);
if(size==0) {
head=temp;
tail=temp;
size++;
return;
}
temp->next=head;
head->prev=temp;
head=temp;
size++;
}
/** Append a node of value val to the last element of the linked list. */
void addAtTail(int val) {
if(size==0) addAtHead(val);
DoublyListNode *temp=new DoublyListNode(val);
tail->next=temp;
temp->prev=tail;
tail=temp;
size++;
}
/** Add a node of value val before the index-th node in the linked list. If index equals to the length of linked list, the node will be appended to the end of linked list. If index is greater than the length, the node will not be inserted. */
void addAtIndex(int index, int val) {
if(index<=0){
addAtHead(val);
}else if(index==size) {
addAtTail(val);
}else if(index>size){
return;
}else{
DoublyListNode *temp=new DoublyListNode(val);
DoublyListNode *cur=head;
for(int i=0;i<index-1;i++){
cur=cur->next;
}
temp->prev=cur;
temp->next=cur->next;
cur->next=temp;
if(temp->next!=NULL) temp->next->prev=temp;//判空
size++;
}
}
/** Delete the index-th node in the linked list, if the index is valid. */
void deleteAtIndex(int index) {
if(size==0) return;
if(index<0||index>=size){
return;
}
//头部删除,需要修改head
if(index==0){
if(head->next==NULL){ head=NULL;tail=NULL;size--;return;}
head=head->next;
head->prev=NULL;
size--;
return ;
}
//尾部删除;需要修改tail
if(index==size-1){
tail=tail->prev;
tail->next=NULL;
size--;
return;
}
//其他位置
DoublyListNode *temp=head;
for(int i=0;i<index;i++){
temp=temp->next;
}
if(temp->next!=NULL){
temp->prev->next=temp->next;
temp->next->prev=temp->prev;
delete temp;
}else{
temp->prev->next=NULL;
}
size--;
}
};
/**
* Your MyLinkedList object will be instantiated and called as such:
* MyLinkedList* obj = new MyLinkedList();
* int param_1 = obj->get(index);
* obj->addAtHead(val);
* obj->addAtTail(val);
* obj->addAtIndex(index,val);
* obj->deleteAtIndex(index);
*/