單鏈表的基本操作及連結串列面試題
單鏈表的基本操作及連結串列面試題
程式程式碼如下:
LinkList.h
#ifndef __LINKLIST_H__
#define __LINKLIST_H__
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef int DataType;
typedef struct Node
{
DataType data;
struct Node* next;
}Node, *pNode, List, *pList;
void InitLinkList (pList* pplist);
pNode BuyNode(DataType d);
void DestroyLinkList(pList* pplist);
void PushBack(pList* pplist, DataType d);
void PopBack(pList* pplist);
void PushFront(pList* pplist, DataType d);
void PopFront(pList* pplist);
pNode Front(pNode pHead);
pNode Back(pNode pHead);
pNode Find(pList plist, DataType d) ;
//在指定位置之前插入一個值
void Insert(pList* pplist, pNode pos, DataType d);
//指定位置刪除
void Erase(pList* pplist, pNode pos);
void Remove(pList* pplist, DataType d);
void RemoveAll(pList* pplist, DataType d);
void EraseNotTailNode(pNode pos);
void PrintLinkList(pList plist);
int GetListLength(pList plist);
//連結串列面試題
//1. 逆序列印單項鍊表
void PrintTailToHead(pList plist);
//2.獲取單鏈表的最後一個節點
pNode SListBack(pList plist);
// 在單鏈表非頭結點前插入新節點,要求不能遍歷連結串列
void InsertPosFront(pNode pos, DataType data);
// 用氣泡排序對單鏈表進行排序
void BubbleSort(pNode* pHead);
// 查詢單鏈表的中間結點,要求只能遍歷一次連結串列
pNode FindMiddleNode(pNode pHead);
// 查詢單鏈表的倒數第K個結點,要求只能遍歷一次連結串列
pNode FindLastKNode(pNode pHead, int K);
// 單鏈表的逆置
void ReverseList(pNode* pHead);
pNode ReverseListOP(pNode pHead);
// 合併兩個有序連結串列,合併成功後依然有序
pNode MergeList(pNode pHead1, pNode pHead2);
// 用單鏈表模擬實現約瑟夫環
pNode JosephCircle(pNode pHead, int M);
// 檢測單鏈表是否帶環
pNode HasListCircle(pNode pHead);
// 求環的長度
int GetCircleLen(pNode pHead);
// 求環的入口點
pNode GetEnterNode(pNode pHead, pNode pMeetNode);
// 判斷兩個單鏈表是否相交(連結串列不帶環)
int IsListCross(pNode pHead1, pNode pHead2);
// 若相交,求交點
pNode GetCrossNode(pNode pHead1, pNode pHead2);
// 檢測兩個連結串列是否相交,連結串列可能帶環
pNode IsListCrossWithCircle(pNode pHead1, pNode pHead2);
#endif //__LINKLIST_H__
LinkList.c
#include "Linklist Interface.h"
void InitLinkList(pList* pplist)
{
assert(pplist);
*pplist = NULL;
}
pNode BuyNode(DataType d)
{
pNode newNode = (pNode)malloc(sizeof(Node));
/*if (newNode == NULL)
{
perror("malloc");
exit(EXIT_FAILURE);
}*/
if (NULL == newNode)
{
assert(0);
return NULL;
}
newNode->data = d;
newNode->next = NULL;
newNode->rand = NULL;
return newNode;
}
void DestroyLinkList(pList* pplist)
{
assert(pplist);
pNode cur = *pplist;
while (cur)
{
pNode del = cur;
cur = cur->next;
free(del);
del = NULL;
}
*pplist = NULL;
}
void PushBack(pList* pplist, DataType d)
{
assert(pplist);
pNode newNode = BuyNode(d);
pNode tail = *pplist;
if (*pplist == NULL)
{
*pplist = newNode;
return;
}
while (tail->next)
{
tail = tail->next;
}
tail->next = newNode;
}
void PopBack(pList* pplist)
{
assert(pplist);
pNode tail = *pplist;
pNode pre = NULL;
if (*pplist == NULL)
return;
if (tail->next == NULL)
{
free(*pplist);
*pplist = NULL;
return;
}
while (tail->next != NULL)
{
pre = tail;
tail = tail->next;
}
free(tail);
pre->next = NULL;
}
void PushFront(pList* pplist, DataType d)
{
assert(pplist);
if (*pplist == NULL)
*pplist = BuyNode(d);
else
{
pNode newNode = BuyNode(d);
newNode->next = *pplist;
*pplist = newNode;
}
}
void PopFront(pList* pplist)
{
assert(pplist);
pNode cur = *pplist;
if (*pplist == NULL)
return;
*pplist = cur->next;
free(cur);
cur = NULL;
}
pNode Front(pNode pHead)
{
if (NULL == pHead)
return NULL;
return pHead;
}
pNode Back(pNode pHead)
{
if (NULL == pHead)
return NULL;
while (NULL != pHead->next)
pHead = pHead->next;
return pHead;
}
pNode Find(pList plist, DataType d)
{
while (plist)
{
if (d == plist->data)
return plist;
plist = plist->next;
}
return NULL;
}
//在指定位置之前插入一個值
void Insert(pList* pplist, pNode pos, DataType d)
{
assert(pplist);
assert(pos);
if (*pplist == NULL)
PushFront(pplist, d);
else
{
pNode cur = NULL;
pNode tail = *pplist;
while (tail->next != pos)
tail = tail->next;
cur = BuyNode(d);
tail->next = cur;
cur->next = pos;
}
}
//指定位置刪除
void Erase(pList* pplist, pNode pos)
{
assert(pplist);
assert(pos);
if (*pplist == NULL)
return;
if ((NULL == (*pplist)->next) || (*pplist == pos))
PopFront(pplist);
else
{
pNode tmp = *pplist;
while (tmp->next != pos)
tmp = tmp->next;
tmp->next = pos->next;
free(pos);
pos = NULL;
}
}
void Remove(pList* pplist, DataType d)
{
assert(pplist);
if (NULL == *pplist)
return;
if (d == (*pplist)->data)
PopFront(pplist);
else
{
pNode tmp = *pplist;
while (tmp->next->data != d)
tmp = tmp->next;
pNode pos = tmp->next;
tmp->next = pos->next;
free(pos);
pos = NULL;
//pNode pos = Find(*pplist, d);
}
}
void RemoveAll(pList* pplist, DataType d)
{
assert(pplist);
pNode tmp = *pplist;
pNode cur = *pplist;
if (NULL == *pplist)
return;
if (d == (*pplist)->data)
PopFront(pplist);
while (cur)
{
if (d == cur->data)
{
tmp->next = cur->next;
free(cur);
cur = tmp->next;
}
else
{
tmp = cur;
cur = cur->next;
}
}
}
void EraseNotTailNode(pNode pos)
{
assert(pos);
pNode del = pos->next;
if (NULL == del)
return;
pos->data = del->data;
pos->next = del->next;
free(del);
del = NULL;
}
void PrintLinkList(pList plist)
{
pNode tmp = plist;
while (tmp)
{
printf("%d-->", tmp->data);
tmp = tmp->next;
}
printf("NULL\n");
}
int GetListLength(pList plist)
{
int count = 0;
while (plist)
{
count++;
plist = plist->next;
}
return count;
}
//連結串列面試題
//1. 逆序列印單項鍊表
void PrintTailToHead(pList plist)
{
if (plist == NULL)
{
printf("NULL");
return;
}
else
{
PrintTailToHead(plist->next);
printf("<--%d", plist->data);
}
//printf("\n");
}
//2.獲取單鏈表的最後一個節點
pNode SListBack(pList plist)
{
if (NULL == plist)
return NULL;
while (plist->next)
{
plist = plist->next;
}
return plist;
}
// 在單鏈表非頭結點前插入新節點,要求不能遍歷連結串列
void InsertPosFront(pNode pos, DataType data)
{
pNode pNewNode;
pNode cur;
DataType tmp = 0;
assert(pos);
if (NULL == pos)
return;
pNewNode = BuyNode(data);
cur = pos;
pNewNode->next = cur->next;
cur->next = pNewNode;
tmp = pNewNode->data;
pNewNode->data = cur->data;
cur->data = tmp;
}
// 用氣泡排序對單鏈表進行排序
void BubbleSort(pNode* pHead)
{
pNode cur = (*pHead);
pNode tail = NULL;
DataType tmp = 0;
if (NULL == (*pHead) || NULL == (*pHead)->next)
return;
while (cur != tail)
{
while (cur->next != tail)
{
if (cur->data > cur->next->data)
{
tmp = cur->next->data;
cur->next->data = cur->data;
cur->data = tmp;
}
cur = cur->next;
}
tail = cur;
cur = (*pHead);
}
}
// 查詢單鏈表的中間結點,要求只能遍歷一次連結串列
pNode FindMiddleNode(pNode pHead)
{
pNode fast = pHead;
pNode slow = pHead;
if (NULL == pHead)
return NULL;
while (fast)
{
if (fast->next)
fast = fast->next->next;
else
{
fast = fast->next;
break;
}
slow = slow->next;
}
return slow;
}
// 查詢單鏈表的倒數第K個結點,要求只能遍歷一次連結串列
pNode FindLastKNode(pNode pHead, int K)
{
pNode fast = pHead;
pNode slow = pHead;
if (NULL == pHead || 0 == K)
return NULL;
while(K--)
fast = fast->next;
while (fast)
{
fast = fast->next;
slow = slow->next;
}
return slow;
}
// 單鏈表的逆置
void ReverseList(pNode* pHead)
{
pNode cur = (*pHead)->next;
pNode tmp = NULL;
assert(pHead);
if (NULL == (*pHead))
return;
(*pHead)->next = NULL;
while (cur)
{
tmp = cur;
cur = cur->next;
tmp->next = (*pHead);
(*pHead) = tmp;
}
}
pNode ReverseListOP(pNode pHead)
{
pNode cur = pHead;
pNode NewHead = NULL;
pNode tmp = NULL;
if (NULL == pHead || NULL == pHead->next)
return NULL;
while (cur)
{
tmp = cur->next;
cur->next = NewHead;
NewHead = cur;
cur = tmp;
}
return NewHead;
}
// 合併兩個有序連結串列,合併成功後依然有序
pNode MergeList(pNode pHead1, pNode pHead2)
{
pNode pNewNode = NULL;
pNode pNewHead = NULL;
pNode p1 = pHead1;
pNode p2 = pHead2;
if (NULL == p1)
return p2;
if (NULL == p2)
return p1;
if (p1->data > p2->data)
{
pNewNode = p2;
p2 = p2->next;
pNewHead = pNewNode;
}
else
{
pNewNode = p1;
p1 = p1->next;
pNewHead = pNewNode;
}
while (NULL != p1 && NULL != p2)
{
if (p1->data > p2->data)
{
pNewNode->next = p2;
p2 = p2->next;
pNewNode = pNewNode->next;
}
else
{
pNewNode->next = p1;
p1 = p1->next;
pNewNode = pNewNode->next;
}
}
if (NULL == p1)
{
pNewNode->next = p2;
return pNewHead;
}
if (NULL == p2)
{
pNewNode->next = p1;
return pNewHead;
}
}
// 用單向迴圈連結串列模擬實現約瑟夫環
pNode JosephCircle(pNode pHead, int M)
{
int num;
pNode pre = NULL;
pNode cur = pHead;
if (NULL == pHead)
return NULL;
if (1 != M)
{
while (cur->next != cur)
{
num = M;
while (--num)
{
pre = cur;
cur = cur->next;
}
pre->next = cur->next;
free(cur);
cur = pre->next;
}
return cur;
相關推薦
單鏈表的基本操作及連結串列面試題
單鏈表的基本操作及連結串列面試題
程式程式碼如下:
LinkList.h
#ifndef __LINKLIST_H__
#define __LINKLIST_H__
#include <stdio.h>
#include <stdlib.
單鏈表基本操作(刪除連結串列中最大元素)
題目描述:
設計一個演算法,刪除一個單鏈表L中元素值最大的節點(假設這樣的節點唯一)
解題思路:
在單鏈表中刪除一個節點先要找到它的前驅節點,用指標p掃描整個單鏈表,pre指向節點p的前驅節點,在掃描時用maxp指向data域值最大的節點,maxpre指向maxp所指節點的前驅節點,當連
C++ 單鏈表基本操作分析與實現 連結串列 連結串列是一種物理儲存單元上非連續、非順序的儲存結構,資料元素的邏輯順序是通過連結串列中的指標連結次序實現的。連結串列由一系列結點(連結串列中每一個元素稱為結點)組成,結
連結串列
連結串列是一種物理儲存單元上非連續、非順序的儲存結構,資料元素的邏輯順序是通過連結串列中的指標連結次序實現的。連結串列由一系列結點(連結串列中每一個元素稱為結點)組成,結點可以在執行時動態生成。每個結點包括兩個部分:一個是儲存資料元素的資料域,另一個是儲存下一個結點地址的指標域。 相比於線性表
資料結構之連結串列(1):單鏈表基本操作
1.前言
1.1宣告
文章中的文字可能存在語法錯誤以及標點錯誤,請諒解;
如果在文章中發現程式碼錯誤或其它問題請告知,感謝!
2.關於連結串列
2.1什麼是連結串列
連結串列可以看成一種在物理儲存單元上的非連續、非順序儲存的資料結構,該資
完成雙鏈表的一些基本操作(連結串列的建立,雙向輸出,插入,刪除)
#include "stdafx.h"
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
typedef struct dlink_node
{
int info;
單鏈表 基本操作(元素遞增排序)
題目描述:
有一個帶頭節點的單鏈表L(至少有一個數據節點),設計一個演算法使其元素遞增有序排列。
解題思路:
由於單鏈表L中有一個以上的資料節點,首先構造一個只含有頭結點和首節點的有序單鏈表(只含有一個數據節點的單鏈表一定是有序的),然後掃描單鏈表L餘下的節點(由P指向),在有序單鏈表中
單鏈表 簡單題(單鏈表基本操作)
題目描述:
有一個帶頭結點的單鏈表L=(a1,b1,a2,b2,......an,bn),設計一個演算法將其拆分成兩個帶頭結點的單鏈表L1和L2,其中L1=(a1,a2,a3...an),L2=(b1,b2,b3....bn),要求L1使用L的頭結點。
解題思路:
利用原單鏈表L中的所有
C 資料結構中單鏈表基本操作
C中的typedef
C中的typedef關鍵字作用是為一種資料型別定義一個新名字,這樣做的目的有兩個,一是給變數定義一個易記且意義明確的新名字,如:
typedef unsigned char BYTE;
把unsigned char型別自命名為BYTE。另一個目的是
建立一個單鏈表,並刪除連結串列中值為W的元素
#include<iostream>
#include<algorithm>
#include<string.h>
#include<stdio.h>
#include<malloc.h>
using namespace std;
typede
建立單鏈表並原地將連結串列逆序
#include<iostream>
#include<stdio.h>
using namespace std;
#define MAXSIZE 5
#define ERROR -1;
#define CORRECT 1;
typedef struct List{
【資料結構】單鏈表-----基本操作
刪除指定位置的節點
void Erase(pList * pplist, pNode pos)
{
assert(pplist != NULL);
assert(pos != NULL);
if (*pplist == pos)//如果指向第一個節點
c++學習筆記—單鏈表基本操作的實現
用c++語言實現的單鏈表基本操作,包括單鏈表的建立(包括頭插法和尾插法建表)、結點的查詢、刪除、排序、列印輸出、逆置、連結串列銷燬等基本操作。
IDE:vs2013
具體實現程式碼如下:
#include "stdafx.h"
#include <malloc.h
單鏈表基本操作java實現
單鏈表基本操作 - java實現
1.單鏈表學習了好久,今天終於有時間寫一下了,帶頭結點的單鏈表上的基本操作,Java實現。
(1) 先來個介面
public interface IList {
public void clear(); //清空連結串列
publi
Java單鏈表基本操作(七)--排序
單鏈表的插入排序比陣列麻煩,因為每次都都要從頭節點開始往後遍歷,頭節點也需要單獨處理
package listnode;
/**
* @author Gavenyeah
* @date St
Java單鏈表基本操作(八)--合併兩個有序單鏈表
package listnode;
/**
* @author Gavenyeah
* @date Start_Time:2016年4月1日 下午15:01:47
* @date End_Ti
c++實現單鏈表基本操作
程式媛決定好好學習寫程式碼
連結串列是一種物理儲存單元上非連續、非順序的儲存結構,資料元素的邏輯順序是通過連結串列中的指標連結次序實現的。連結串列由一系列結點(連結串列中每一個元素稱為結點)組成,結點可以在執行時動態生成。每個結點包括兩個部分:一個是儲存資料元素的資料域,
單鏈表的建立(靜態連結串列,動態連結串列)
連結串列是一種很重要的資料結構,在實際工作中也有著很多的應用,這次我們先討論一下最簡單的單鏈表。
關於單鏈表的操作有很多,當然最基本的就是要建立一個單鏈表,對於單鏈表來說,可以按照型別分為靜態連結串列和動態連結串列。
1.靜態連結串列
靜態連結串
無頭結點單鏈表基本操作
動態順序表
linklist.h
#pragma once
#include <stdio.h>
#include <assert.h>
#include <malloc.h>
#include <stdlib.h&
單鏈表基本操作的C語言實現(鏈式儲存結構)
#include<stdio.h>
#include<stdlib.h>
typedef int DataType;
typedef struct Node{
DataType data;
struct Node *next;
}
單鏈表基本操作(1)
單鏈表基本操作
建立
建立
頭插入載入
尾插入載入
建立空連結串列
建立一個單鏈表,且為空表,並且返回連結串列
建立結構型別,在CS.c檔案中
typedef struct node{
int data;
struc