【C++】連結串列的實現
阿新 • • 發佈:2018-11-08
1.定義
//單向
struct Node{
int value;
Node * next;
};
//雙向
struct DNode{
int value;
DNode * left;
DNode * right;
};
2.基本操作
(1)插入節點
//p節點後插入值為i的節點
void insertNode(Node *p, int i){
Node* node = new Node;
node->value = i;
node->next = p->next;
p- >next = node;
}
(2)刪除節點
void deleteNode(Node *p){
p->value = p->next->value;
p->next = p->next->next;
}
(3)反向遍歷連結串列
//1.stack
void printLinkedListReversinglyByStack(Node *head){
stack<Node* > nodesStack;
Node* pNode = head;
//遍歷連結串列
while (pNode != NULL) {
nodesStack.push(pNode);
pNode = pNode->next;
}
while (!nodesStack.empty()) {
pNode=nodesStack.top();
printf("%d\t", pNode->value);
nodesStack.pop();
}
}
//2.遞迴
void printLinkedListReversinglyRecursively(Node *head){
if (head!=NULL) {
if (head->next!=NULL) {
printLinkedListReversinglyRecursively(head->next);
}
printf("%d\t", head->value);
}
}
(4)找出中間節點
Node* findMidNode(Node* head){
Node* slow = head;
Node* fast = head;
while (fast->next != 0&&fast->next->next!=0) {
slow = slow->next;
fast = fast->next->next;
}
return slow;
}
(5)找出倒數k個節點
Node* findKNode(Node* head,int k){
Node *temp1 = head;
Node *temp2 = head;
while (k-->0) {
if(temp2 == NULL){
return NULL;
}
temp2 =temp2->next;
}
while (temp2->next != NULL&&temp2->next->next!=NULL) {
temp1 = temp1->next;
temp2 = temp2->next->next;
}
return temp1;
}
(6)翻轉連結串列
Node * reverseLinkedList(Node* head,int k){
Node *reversedHead = NULL;
Node *pNode = head;
Node *pre = NULL;
while (pNode!=NULL) {
if (pNode->next==NULL) {
reversedHead = pNode;
}
Node* nxt = pNode->next;
pNode->next = pre;
pre=pNode;
pNode=nxt;
}
return reversedHead;
}
(7)判斷是否相交
思路:
如果兩個連結串列相交,其形狀必為y形,而不可以能為x形,即兩條連結串列必有相同的尾節點。首先,計算得到兩個連結串列的長度:m,n,求得兩個連結串列長度之差distance=|m-n|,讓較長得那個連結串列事先走distance步,這樣,若是連結串列相交得話,二者指標必相撞,相撞點即為相交點。
Node* findCrosspoint(Node* l1, Node* l2){
int m = getLinkedListLength(l1);
int n = getLinkedListLength(l2);
int distance=0;
Node *temp1= l1;
Node *temp2= l2;
if (m>n) {
distance = m - n;
while (distance>0) {
distance--;
temp1=temp1->next;
}
} else{
distance = n - m;
while (distance>0) {
distance--;
temp2 = temp2->next;
}
}
while(temp1!=temp2&&temp1->next!=NULL&&temp2->next!=NULL){
temp1=temp1->next;
temp2=temp2->next;
}
if(temp1 == temp2){
return temp1;
}
return 0;
}
(8)判斷連結串列是否有環路,獲取連線點,計算環的長度
思路:
判斷是否有環:slow和fast,slow指標每次走一步,fast指標每次走兩步,若是連結串列有環,fast必能追上slow(相撞),若fast走到NULL,則不含有環。
判斷環的長度:在相撞點處,slow和fast繼續走,當再次相撞時,slow走了length步,fast走了2*length步,length即為環得長度。
環得連線點:slow和fast第一次碰撞點到環的連線點的距離=頭指標到環的連線點的距離,此式可以證明,詳見上面連結。
bool containLoop(Node* head){
if (head==NULL) {
return false;
}
Node* slow = head;
Node* fast = head;
while (slow!=fast&&fast->next!=NULL) {
slow = slow->next;
fast = fast->next->next;
}
if (fast==NULL) {
return false;
}
return true;
}
int getLoopLength(Node* head){
if (head==NULL) {
return 0;
}
Node* slow = head;
Node* fast = head;
while (slow!=fast&&fast->next!=NULL) {
slow = slow->next;
fast = fast->next->next;
}
if (fast==NULL) {
return 0;
}
//slow和fast首次相遇後,slow和fast繼續走
//再次相遇時,即slow走了一圈,fast走了兩圈
int length = 0;
while (slow!=fast) {
length++;
slow = slow->next;
fast = fast->next->next;
}
return length;
}
Node* getJoinpoit(Node* head){
if (head==NULL) {
return NULL;
}
Node* slow = head;
Node* fast = head;
while (slow!=fast&&fast->next!=NULL) {
slow = slow->next;
fast = fast->next->next;
}
if (fast==NULL) {
return NULL;
}
Node* fromhead = head;
Node* fromcrashpoint = slow;
while (fromcrashpoint!=fromhead) {
fromhead = fromhead->next;
fromcrashpoint = fromcrashpoint->next;
}
return fromhead;
}
(9)二叉樹和雙向連結串列的轉換
struct BinaryTreeNode{
int value;
BinaryTreeNode* left;
BinaryTreeNode* right;
};
BinaryTreeNode* convertNode(BinaryTreeNode* pNode, BinaryTreeNode** pLastNodeInLast){
if (pNode == NULL) {
return NULL;
}
BinaryTreeNode *pCurrent = pNode;
if (pCurrent->left != NULL) {
convertNode(pCurrent->left, pLastNodeInLast);
}
pCurrent->left = *pLastNodeInLast;
if (*pLastNodeInLast != NULL) {
(*pLastNodeInLast)->right=pCurrent;
}
*pLastNodeInLast = pCurrent;
if (pCurrent->right != NULL) {
convertNode(pCurrent->right, pLastNodeInLast);
}
return NULL;
}
BinaryTreeNode* convertBTToDLL(BinaryTreeNode* root){
BinaryTreeNode *pLastNodeInLast = NULL;
convertNode(root, &pLastNodeInLast);
BinaryTreeNode *pHeadOfList = pLastNodeInLast;
while (pHeadOfList != NULL && pHeadOfList->left != NULL) {
pHeadOfList = pHeadOfList->left;
}
return pHeadOfList;
}