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< */ 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; } /* */ 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"); }