List

include

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<data<

*/

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

}

你可能感兴趣的:(List)