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");

}

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

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