List

include<iostream>

using namespace std;

//單鏈表

typedef struct Lnode{

int data;

struct Lnode *next;

}Lnode;

//雙鏈表

typedef struct DLnode{

int data;

struct DLnode *next;

}DLnode;

/*

尾插法建立單鏈表

*/

Lnode * Create(Lnode *head, int *a, int n){

Lnode *first, *node;

first = (Lnode *)malloc(sizeof(Lnode)); //頭結點

head = first;

first->next = NULL;

for (int i = 0; i < n; ++i){

node = (Lnode *)malloc(sizeof(Lnode));

node->data = *(a + i);

first->next = node;

first = first->next;

}

first->next = NULL;

return head;

}

/*

頭插法建立單鏈表

*/

Lnode * HeadCreate(Lnode *head, int *a, int n){

Lnode *first, *node;

first = (Lnode *)malloc(sizeof(Lnode)); //頭結點

head = first;

first->next = NULL;

for (int i = 0; i < n; ++i){

node = (Lnode *)malloc(sizeof(Lnode));

node->data = *(a + i);

node->next = first->next;

first->next = node;

}

return head;

}

/*

在指定位置插入節點val

*/

Lnode * Insert(Lnode * head, int n, int val){

Lnode *p = head;

Lnode node = (Lnode)malloc(sizeof(Lnode));

for (int i = 0; i < n - 1; ++i){

p = p->next;

}

node->data = val;

node->next = p->next;

p->next = node;

return head;

}

/*

刪除 data 為val的某個節點

*/

int Del(Lnode *head, int val){

Lnode*p, *q;

p = head; //傳入頭指針,然后p保存頭指針信息,修改p,即等同于修改head頭指針

while (p->next != NULL){ //p指向刪除節點的前一個節點

if (p->next->data == val)

{

break;

}

p = p->next;

}

if (p->next == NULL){

return 0;

}

else{

q = p->next;

p->next = q->next;

free(q);

return 1;

}

}

/*

單鏈表反轉

*/

Lnode* Reverse(Lnode *head){

Lnode *first = head->next, *tmp;

head->next = NULL;

while (first != NULL)

{

tmp = first->next;

first->next = head->next;

head->next = first;

first = tmp;

}

return head;

}

/*

  • 構建有環單鏈表

*/

Lnode *CirLnode(Lnode *head, int num) {

Lnode *tmp, *tail;

tmp = tail = head->next;

for (int i = 1; i < num; ++i) {

tmp = tmp->next;

}

while (tail->next != NULL) {

tail = tail->next;

}

tail->next = tmp;

return head;

}

/*

  • 判斷單鏈表是否有環

*/

int IsCir(Lnode *head) {

Lnode *first, *last;

first = head;

last = head;

while (last != NULL && last->next != NULL) {

last = last->next->next;

first = first->next;

if (first == last) {

cout << first->data << endl; //在環中相遇的點,不一定是環的初始點

//求環的初始點

first = head;

while (first->next!=NULL){ //first和last在環中相遇的時候,使first指針回到head節點,last不動,然后first和last都每次走一步,兩者再次相遇的點就是環的初始節點

first = first->next;

last = last->next;

if (first == last){

cout << "初始環點" << first->data << endl;

break;

}

}

return 1;

}

}

return 0;

}

/*

約瑟夫環問題

*/

int JoseCircle(Lnode *head,int num){

Lnode p = head,tmp,*q;

int i = 1;

q = p->next;

while (p!=q){

i++;

p = q;

q = q->next;

if (i == num){

tmp = q;

p->next = tmp->next;

q = p->next;

free(tmp);

i = 1;

}

}

return q->data;

}

/*

查找單鏈表中的倒數第K個結點(k > 0)

*/

int FindLast(Lnode * head, int k){

Lnode *p, *q;

q = head;

p = q->next;

for (int i = 0; i < k; ++i){ //使用兩個指針,前面的指針走到正K,后面的指向第一個,兩者相差為k-1,然后同時走,直到前面走到最后,后指針的位置即為所求

q = q->next;

}

if (q == NULL){ //k大于鏈表個數

return -1;

}

while (q->next != NULL){

p = p->next;

q = q->next;

}

/*

while(p){

p=p->next;

i++;

if(i>k) q=q->next; //p先走,只有存在p走過了K個節點,q才開始走,當p走到終點,q指向倒數K個節點

}

if(q==head) return 0; //q要么指向頭結點,要么指向倒數第K個

else cout<<q->data<<endl;

*/

return p->data;

}

/*

  • 刪除相同節點

*/

Lnode *DelSame(Lnode *head) {

Lnode *p, *q, *tmp;

p = head->next;

while (p != NULL) {

q = p;

while (q->next != NULL) {

if (q->next->data == p->data) {

tmp = q->next;

q->next = tmp->next;

free(tmp);

}

else{

q = q->next;

}

}

p = p->next;

}

return head;

}

/*

查找單鏈表的中間節點

*/

int FindMid(Lnode *head){

Lnode *p, *q;

p = q = head->next;

while (q->next != NULL){

if (q->next->next != NULL){

p = p->next;

q = q->next->next;

}

else{

break;

}

}

return p->data;

}

/*

統計節點的個數

*/

int CalcNum(Lnode *head){

int n = 0;

Lnode *tmp = head;

if (head->next == NULL){

return n;

}

else{

while (tmp->next != NULL){

n++;

tmp = tmp->next;

}

return n;

}

}

/*

  • 合并兩個有序鏈表

*/

Lnode *MergeLnode(Lnode *h1, Lnode *h2) {

Lnode *p1, *p2, *p3, *q;

p1 = h1->next, p2 = h2->next;

q = p3 = h1;

q->next = NULL;

while (p1 != NULL && p2 != NULL) {

if (p1->data <= p2->data) {

q->next = p1;

p1 = p1->next;

}

else {

q->next = p2;

p2 = p2->next;

}

q = q->next;

}

if (p1 != NULL) q->next = p1;

if (p2 != NULL) q->next = p2;

return p3;

}

/*

  • 求A,B鏈表的差集A-B

*/

Lnode *Diff(Lnode *h1, Lnode *h2) {

Lnode *p = h1, *q = h2;

Lnode *tmp;

while (p->next != NULL && q->next != NULL) {

if (p->next->data < q->next->data) {

p = p->next;

}

else if (p->next->data > q->next->data) {

q = q->next;

}

else {

tmp = p->next;

p->next = tmp->next;

free(tmp);

}

}

return h1;

}

/*

求A,B鏈表的交集

*/

void Common(Lnode *h1, Lnode *h2){

Lnode *p = h1, *q = h2;

while (p->next != NULL && q->next != NULL) {

if (p->next->data < q->next->data) {

p = p->next;

}

else if (p->next->data > q->next->data) {

q = q->next;

}

else {

cout << p->next->data << " ";

p = p->next;

q = q->next;

}

}

cout << endl;

}

/*

刪除單鏈表中的最小值節點

*/

Lnode *DelMin(Lnode *head){

Lnode *q = head->next, min = q,tmp=head;

while (q != NULL && q->next!=NULL){

if (q->next->data < min->data){

tmp = q;

min = q->next;

}

q = q->next;

}

tmp->next = min->next;

free(min);

return head;

}

/*

將A鏈表拆分成A,B,其中A是data為奇數的點,B是data為偶數的點,順序不變

*/

Lnode * SplitLink(Lnode *h1, Lnode *h2){

Lnode p = h1,t ;

Lnode *q = (Lnode *)malloc(sizeof(Lnode));

h2 = q;

q->next = NULL;

while (p->next != NULL){

if (p->next->data % 2 == 0){ //如果是偶數,就取出 放到B中,否則就繼續前進,然后A就剩余奇數

t = p->next;

p->next = t->next;

t->next = NULL;

q->next = t;

q = q->next;

}

else{

p = p->next;

}

}

return h2;

}

/*

按照val值將單鏈表分成左右部分,左邊比它小,右邊比它大

*/

Lnode * Partation(Lnode *head,int val){

Lnode *p = head;

Lnode *small, *equal, *big; //將單鏈表拆成三個鏈表, 分別定義三個頭指針,

small = equal = big = NULL;

Lnode * smallA, *equalA, *bigA ; //三個鏈表的尾指針

smallA = equalA = bigA = NULL;

while (p->next!=NULL){

if (p->next->data < val){

if (small == NULL){ //初始時,頭尾指針均指向第一個進入大,等,小的節點

smallA = small = p->next;

}

else{

smallA->next = p->next; //不是第一個節點的時候,采用尾插法將節點插入鏈表

smallA = smallA->next;

}

}

else if (p->next->data == val){

if (equal == NULL){

equalA = equal = p->next;

}

else{

equalA->next = p->next;

equalA = equalA->next;

}

}

else {

if (big == NULL){

bigA = big = p->next;

}

else{

bigA->next = p->next;

bigA = bigA->next;

}

}

p = p->next;

}

if (small!=NULL && equalA != NULL) { //當小鏈表不為空,且等鏈表不為空,鏈接兩個鏈表,等鏈表后置為空

equalA->next = NULL;

smallA->next = equal;

}

if (equalA!=NULL && bigA != NULL) { // 同理鏈接等鏈表和大鏈表

bigA->next = NULL;

equalA->next = big;

}

head->next = small != NULL ? small : equal != NULL ? equal : big;

return head;

}

/*

正序打印單鏈表

*/

void show(Lnode * head){

while (head->next != NULL){

cout << head->next->data << " ";

head = head->next;

}

cout << endl;

}

/*

逆序打印單鏈表

*/

void ShowTail(Lnode *head) { //print from tail,顛倒順序的問題,采用棧,并且去掉頭結點

Lnode *p = head;

if (p == NULL) {

return;

}

ShowTail(p->next);

cout << p->data << " ";

}

void tt(int *p){

int a = 3;

int *q = p;

q = &a;

}

void test(Lnode *head){ //一個單鏈表,first指針在前,last指針在后,first置空后,last便訪問不到first后的節點

//last置空后,并不妨礙first訪問后面的節點

Lnode *p = head->next;

Lnode *q = p;

p = p->next->next;

p->next = NULL;

q = q->next;

cout << p->data << endl;

}

void main(){

int a[] = {2,1,3,5,4};

int b[] = { 3,4, 5, 6, 7, 8 };

int lenA = sizeof(a) / sizeof(a[0]);

int lenB = sizeof(b) / sizeof(b[0]);

Lnode *head = NULL, *tail = NULL , *h2=NULL; //頭指針

head = Create(head, a, lenA); //指針作為函數參數時,傳遞的也是指針的地址拷貝,所以指正不會改變,傳入堆指針時,指針的值才會變化

show(head);

tail = HeadCreate(tail, b, lenB);

Reverse(tail);

show(tail);

/*

cout << "節點個數為: " << CalcNum(head) << endl;

*tail = Reverse(tail);

show(tail);

if (Del(head, 4) > 0){

cout << "找到并刪除" << endl;

show(head);

}

Insert(head, 3, 6);

show(head);

cout << "節點個數為: " << CalcNum(head) << endl;

cout << FindMid(head) << endl;

head = DelMin(head);

show(head);

h2=SplitLink(head, h2);

show(head);

show(h2);

int *p = (int *)malloc(sizeof(int));

tt(p);

if (p == NULL){

cout << "null" << endl;

}

else{

cout << " not null" << endl;

}

*/

//head = CirLnode(head, 1);

/*if (IsCir(head)){

cout << "has a circle " << endl;

}

else{

cout << "no circle " << endl;

}*/

//cout << "Last out " << JoseCircle(head, 3) << endl;

//Common(head, tail);

head = Partation(head, 2);

show(head);

free(head);

free(tail);

system("pause");

}

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,517評論 6 539
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,087評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,521評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,493評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,207評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,603評論 1 325
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,624評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,813評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,364評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,110評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,305評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,874評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,532評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,953評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,209評論 1 291
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,033評論 3 396
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,268評論 2 375

推薦閱讀更多精彩內容

  • 背景 一年多以前我在知乎上答了有關LeetCode的問題, 分享了一些自己做題目的經驗。 張土汪:刷leetcod...
    土汪閱讀 12,763評論 0 33
  • 對于單鏈表, 由于每個節點只存儲了向后的指針,到了尾部標識就停止了向后鏈的操作,也就是說按照這樣的方式,只能索引后...
    AceKitty閱讀 1,089評論 0 1
  • //Linked-list#include#includetypedef struct _node{ int va...
    鄭銘皓閱讀 428評論 0 0
  • 題目類型 a.C++與C差異(1-18) 1.C和C++中struct有什么區別? C沒有Protection行為...
    阿面a閱讀 7,698評論 0 10
  • 我將做一個奇怪的實驗:我將把每天的主要行為都記錄下來發出來,然后你們就可以看著我,一步一步看著我,走向成功或者失敗...
    張生好龍閱讀 432評論 7 3